委托(Delegate),BeginInvoke,EndInvoke - 如何清理多个异步调用同一个委托的线程?

3

我创建了一个委托,我打算异步调用它。

模块级别

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) 

该方法运行并执行其所需操作。

异步回调在完成后触发,我在其中执行EndInvoke操作。

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

只要调用委托的BeginInvoke方法的方法在没有BeginInvoke/Thread操作正在运行时运行,它就能正常工作。问题是,当委托上的另一个线程仍在运行且尚未EndInvoke时,可能会调用新线程。
如果需要,程序需要能够同时运行多个委托实例,并且它们都需要完成并调用EndInvoke。一旦我开始另一个BeginInvoke,我就失去了对第一个BeginInvoke的引用,因此无法使用EndInvoke清理新线程。
如何干净地解决这个问题并达到最佳实践?
2个回答

2

你只需要保留一个委托的引用,每次调用时不需要创建新的引用。

与其将 Nothing 传递给 EndInvoke,不如传递 ar。这将给出该特定调用的结果。

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

如果您想要取消特定的调用,那么您需要保存BeginInvoke的结果(它是您在上面回调中收到的IAsyncResult实例)。

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();
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接