【问题标题】:Delegate, BeginInvoke. EndInvoke - How to clean up multiple Async threat calls to the same delegate?委托,开始调用。 EndInvoke - 如何清理对同一委托的多个异步威胁调用?
【发布时间】:2010-02-09 16:39:29
【问题描述】:

我创建了一个我打算调用 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 清理新线程。

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

【问题讨论】:

    标签: vb.net delegates multithreading begininvoke


    【解决方案1】:

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

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

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

    如果您希望能够取消特定的调用,那么您需要保留BeginInvoke 的结果(这与在上面的回调中传递给您的IAsyncResult 的实例相同) .

    【讨论】:

      【解决方案2】:

      您需要在调用 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();
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2017-06-23
        • 1970-01-01
        • 2014-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多