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'd。

如有必要,程序需要能够让委托一次在多个实例中运行,并且它们都需要完成并调用 EndInvoke。一旦我开始另一个 BeginInvoke,我就会失去对第一个 BeginInvoke 的引用,因此我无法使用 EndInvoke 清理新线程。

克服此问题的干净解决方案和最佳实践是什么?

4

2 回答 2

2

您只需要保留对代表的一个引用;您无需在每次调用时都创建一个新的。

而不是传递NothingEndInvoke,传递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 回答