委托,BeginInvoke。 EndInvoke - 如何清除对同一委托的多个异步威胁调用?

时间:2010-02-09 16:39:30

标签: vb.net delegates multithreading begininvoke

我创建了一个我打算调用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) 

该方法运行并完成所需的操作

在完成EndInvoke

时,会触发Asyn回调
Sub AsyncCallback_GetPartListDataFromServer(ByVal ar As IAsyncResult)
    dlgGetPartList.EndInvoke(Nothing)
End Sub

只要在没有正在运行的BeginInvoke / Thread操作的情况下,只在代理上启动BeginInvoke的方法运行,它就会起作用。问题是,当委托中的另一个线程仍在运行且尚未进行EndInvoke时,可以调用新线程。

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

什么是解决此问题的清洁解决方案和最佳做法?

2 个答案:

答案 0 :(得分:2)

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

不是将Nothing传递给EndInvoke,而是传递ar。这将为您提供特定调用的结果。

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

如果您希望能够取消特定的调用,那么您将希望保留BeginInvoke的结果(这是IAsyncResult的相同实例,该结果将传递给您你上面的回调)。

答案 1 :(得分: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();
        }
    }
相关问题