8

GUIのフリーズを回避するために、DBに非同期で接続するメソッドを実行したいと思いました。したがって、私はこれを書きました:

DelegatLoginu dl = ConnectDB;

IAsyncResult ar = dl.BeginInvoke(null, null);

var result = (bool)dl.EndInvoke(ar);

しかし、それはまだ凍っていて、私は理由がわかりません。BeginInvoke呼び出されたコードが別のスレッドで実行されることを保証すると思いました。ありがとうございました!

4

7 に答える 7

12

EndInvoke()の呼び出しは、BeginInvoke()の呼び出しが完了するまでブロックされます。

実行時間の長いメソッドが終了時にコールバックを呼び出すには、この種のパターンが必要です。

public void DemoCallback()
{
    MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    string s ;
    int iExecThread;

    // Create the callback delegate.
    AsyncCallback cb = new AsyncCallback(MyAsyncCallback);

    // Initiate the Asynchronous call passing in the callback delegate
    // and the delegate object used to initiate the call.
    IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, cb, dlgt); 
}

public void MyAsyncCallback(IAsyncResult ar)
{
    string s ;
    int iExecThread ;

    // Because you passed your original delegate in the asyncState parameter
    // of the Begin call, you can get it back here to complete the call.
    MethodDelegate dlgt = (MethodDelegate) ar.AsyncState;

    // Complete the call.
    s = dlgt.EndInvoke (out iExecThread, ar) ;

    MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\", 
                                and the number {1}", s, iExecThread.ToString() ) );
}
于 2010-05-05T09:26:52.787 に答える
5

EndInvoke ここの説明を参照してください。具体的には、次のとおりです。

EndInvoke()関数は、非同期呼び出しの結果を取得するために使用されます。BeginInvoke()の後でいつでも呼び出すことができます。非同期呼び出しがまだ完了していない場合、EndInvoke()は完了するまでブロックします。

于 2010-05-05T09:27:38.993 に答える
2

を呼び出すと、すぐにUIスレッドがブロックされますdl.EndInvoke(ar)。この種の場合、非同期呼び出しを行うという目的全体が無効になります。

于 2010-05-05T09:26:27.247 に答える
1

この質問は非常によくカバーしているので、.NETで非同期モデルを使用するための4つの異なるパターンがあります。

あなたは「私はあなたに電話します」アプローチを使用しています。ただし、作業項目が終了するまで待ちたい場合は、MutexWaitHandle)を使用するのが最善の方法です。

void Run()
{
    Action<string> doWork = DoWork;
    IAsyncResult result = doWork.BeginInvoke("I will call you", null, null);

    // You "call the method" - wait 10 seconds for the method to finish.
    bool success = result.AsyncWaitHandle.WaitOne(10 * 1000);
}

void DoWork()
{
}

ブロックしたくないのではないかと思います。その場合、「ファイアアンドフォーゲット」は頭痛の種を最小限に抑えます。

于 2010-05-12T09:26:16.127 に答える
0

BeginInvokeで呼び出しが完了したときに呼び出されるメソッドを指定します(dl.BeginInvoke(null、OnConnectCompleted)など)。その後、スレッドはブロックされません。

于 2010-05-05T09:28:38.397 に答える
0

代わりにBackgroundWorkerを使用しないのはなぜですか?

于 2010-05-05T09:48:02.083 に答える
0

EndInvoke を呼び出すと、現在のスレッドがブロックされます。EndInvoke を呼び出す代わりに、BeginInvoke にデリゲートを渡す必要があります。

于 2010-05-05T10:57:12.147 に答える