3

スコープ外になった後のデストラクタに問題があります(呼び出し中ですが、しばらくすると、フォームでアクションを実行する必要があります。たとえば、ラジオボタンを変更します)。コードに間違いがある可能性があります。見てください:

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
            EventLogger.Print += delegate(string output)
            { if (!textBox1.IsDisposed) this.Invoke(new MethodInvoker(() => textBox1.AppendText(output + Environment.NewLine)), null); };
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TestClass test = new TestClass();
        }
    }
    public static class EventLogger
    {
        public delegate void EventHandler(string output);
        public static event EventHandler Print;
        public static void AddLog(String TextEvent)
        {
            Print(TextEvent);
        }
    }
    public class TestClass
    {
        public TestClass()
        {
            EventLogger.AddLog("TestClass()");
        }
        ~TestClass()
        {
            EventLogger.AddLog("~TestClass()");
        }
    }

}
4

4 に答える 4

9

そうです、これは C++ ではないからです。ファイナライザ (C++ のようなデストラクタではない) は、オブジェクトが宣言スコープを離れた直後に呼び出されるとは限りません。GC が急降下してクリーンアップすることを決定したときに呼び出されます。

そもそもファイナライザーを使用している理由をお聞きしてもよろしいですか? 可能な限り決定論的に割り当てを解除する必要があるアンマネージ リソースへの参照を維持していますか (そうであれば、IDisposable インターフェイスを参照してください)。C# ファイナライザーの使用例はほとんどなく、それらを実装することは一般的ではありません。

于 2012-06-11T17:52:06.083 に答える
3

C# は C++ ではありません。デストラクタは同期的に実行されません

コードにバグはありませんが、クラスに「IDisposableパターン」を実装して、オブジェクトの一部の破壊が同期的に実行されることを呼び出し元に保証する方法を提供する必要があるようです。

于 2012-06-11T17:54:46.940 に答える
0

ファイナライザーは、スコープ外に出た直後に呼び出されるようには設計されていません。オブジェクトがガベージ コレクションされるときに呼び出されます。これは、範囲外になってから数ミリ秒から数日かかる場合があります。

ファイナライザーは、この種のコード用ではありません。リソースのクリーンアップ専用です。

スコープ外に出た直後に何かを強制することはできませんが、スコープ外に出る直前にClose()オブジェクトが使用されていることを知らせるまたは同様の方法を使用して、オブジェクトに何かをさせることはできます。

例えば:

private void button1_Click(object sender, EventArgs e)
{
    TestClass test = new TestClass();
    // do stuff
    test.Close();
}

注:IDisposable提案されているように を実装することもできますが、この使用法は の意図した使用法に正確には適合しないため、機能しますがIDisposable、少しハックです。

于 2012-06-11T18:03:03.230 に答える