3

Async と呼ぶ予定のデリゲートを作成しました。

モジュールレベル

Delegate Sub GetPartListDataFromServer(ByVal dvOriginal As DataView, ByVal ProgramID As Integer)
Dim dlgGetPartList As GetPartListDataFromServer 

メソッドで使用する次のコード

    Dim dlgGetPartList As New GetPartListDataFromServer(AddressOf AsyncThreadMethod_GetPartListDataFromServer)
    dlgGetPartList.BeginInvoke(ucboPart.DataSource, ucboProgram.Value, AddressOf AsyncCallback_GetPartListDataFromServer, Nothing) 

メソッドが実行され、必要なことを行います

Asyn コールバックは、EndInvoke を実行する完了時に発生します

Sub AsyncCallback_GetPartListDataFromServer(ByVal ar As IAsyncResult)
    dlgGetPartList.EndInvoke(Nothing)
End Sub

これは、デリゲートで BeginInvoke を開始するメソッドが、BeginInvoke/Thread 操作がまだ実行されていないときにのみ実行される限り機能します。問題は、デリゲートの別のスレッドがまだ実行中で、まだ EndInvoke されていないときに、新しいスレッドが呼び出される可能性があることです。

プログラムは、必要に応じて一度に複数のインスタンスでデリゲートを実行できる必要があり、それらすべてが完了して EndInvoke が呼び出される必要があります。別の BeginInvoke を開始すると、最初の BeginInvoke への参照が失われるため、EndInvoke で新しいスレッドをクリーンアップできません。

この問題を解決するためのクリーンなソリューションとベスト プラクティスは何ですか?

4

2 に答える 2

2

保持する必要があるのは、デリゲートへの 1 つの参照だけです。呼び出すたびに新しいものを作成する必要はありません。

Nothingに渡すのではなくEndInvoke、 に渡しarます。これにより、その特定の呼び出しの結果が得られます。

Sub AsyncCallback_GetPartListDataFromServer(ByVal ar As IAsyncResult)
    dlgGetPartList.EndInvoke(ar)
End Sub

特定の呼び出しをキャンセルできるようにしたい場合は、 (上記のコールバックで渡されるBeginInvokeのと同じインスタンスです)の結果を保持する必要があります。IAsyncResult

于 2010-02-09T17:08:15.283 に答える
1

BeginInvoke を呼び出すときに、状態引数としてオブジェクトを渡す必要があります。

    class Program

    {
        delegate void SampleDelegate(string message);

        static void SampleDelegateMethod(string message)
        {
            Console.WriteLine(message);
        }
        static void Callback(object obj)
        {
            IAsyncResult result = obj as IAsyncResult;

            SampleDelegate del = result.AsyncState as SampleDelegate; 
            del.EndInvoke(result);
            Console.WriteLine("Finished calling EndInvoke");
        }
        static void Main()
        {
            for (int i = 0; i < 10; i++)
            {
                // Instantiate delegate with named method:
                SampleDelegate d1 = SampleDelegateMethod;
               //d1 is passed as a state
                d1.BeginInvoke("Hello", Callback, d1);
            }
            Console.WriteLine("Press any key to continue");
            Console.ReadLine();
        }
    }
于 2010-02-09T17:11:54.670 に答える