C# IAsyncResult.IsCompleted、iftAR.AsyncWaitHandle.WaitOne和AsyncCallback的使用条件

C# IAsyncResult.IsCompleted、iftAR.AsyncWaitHandle.WaitOne和AsyncCallback的使用条件,c#,asynchronous,delegates,C#,Asynchronous,Delegates,我正在学习委托的异步概念,在这里,我对使用IAsyncResult.IsCompleted、iftAR.AsyncWaitHandle.WaitOne和AsyncCallback(在其中定义了以IAsyncResult为参数的新函数)之间的区别感到困惑 我很困惑,因为假设您使用while循环检查上述3个值,然后在这3种情况中的每一种情况下,您都在检查while循环是否完成了特定操作的执行。那么,三者之间的区别是什么 案例1代码: static void Main(string[] arg

我正在学习委托的异步概念,在这里,我对使用IAsyncResult.IsCompleted、iftAR.AsyncWaitHandle.WaitOne和AsyncCallback(在其中定义了以IAsyncResult为参数的新函数)之间的区别感到困惑

我很困惑,因为假设您使用while循环检查上述3个值,然后在这3种情况中的每一种情况下,您都在检查while循环是否完成了特定操作的执行。那么,三者之间的区别是什么

案例1代码:

    static void Main(string[] args) 
    {  
     Console.WriteLine("***** Async Delegate Invocation *****");  
      // Print out the ID of the executing thread.  
     Console.WriteLine("Main() invoked on thread {0}.",Thread.CurrentThread.ManagedThreadId);  
      // Invoke Add() on a secondary thread.  
    BinaryOp b = new BinaryOp(Add); 
  IAsyncResult iftAR = b.BeginInvoke(10, 10, null, null);  
  // This message will keep printing until   
// the Add() method is finished.   
while(!iftAR.IsCompleted)  
 {   
  Console.WriteLine("Doing more work in Main()!"); 
    Thread.Sleep(1000);   
}  
 // Now we know the Add() method is complete. 
  int answer = b.EndInvoke(iftAR); 
     Console.WriteLine("10 + 10 is {0}.", answer);   
    Console.ReadLine();
     } 

     static int Add(int x, int y)    
     {     
      // Print out the ID of the executing thread.  
         Console.WriteLine("Add() invoked on thread {0}.", Thread.CurrentThread.ManagedThreadId);  
          // Pause to simulate a lengthy operation.   
        Thread.Sleep(5000);    
       return x + y; 
        }   
案例2代码:如果我们用foll代码替换while循环:

while (!iftAR.AsyncWaitHandle.WaitOne(1000, true))
 {  
 Console.WriteLine("Doing more work in Main()!"); 
}
案例3代码:如果我们将案例1中的while循环替换为foll代码并添加AddComplete方法:

 while (!isDone)    
   {  
       Thread.Sleep(1000);  
       Console.WriteLine("Working...."); 
      }   

 static void AddComplete(IAsyncResult itfAR) 
   {     
  Console.WriteLine("AddComplete() invoked on thread {0}.",         Thread.CurrentThread.ManagedThreadId);      
 Console.WriteLine("Your addition is complete");   
    isDone = true;  
   }   

IAsyncResult
是APM模式的一部分,APM模式本身与委托关系不大,只是使用委托进行回调。这个模式需要被视为它自己的(相当复杂)主题。

尽管如此,总结上的区别如下:

IsComplete
只是一个标志,用于轮询/检查操作是否已完成或是否仍在运行

WaitHandle
包装了一个操作系统原语,并允许在异步操作期间不使用任何CPU加入线程,也可以选择超时。当
WaitOne
上的超时设置为0时,操作基本上与
IsComplete
相同,但开销要高得多

然而,
回调
允许启动一个操作并“忘记”它;操作完成时将调用回调,因此允许在该点继续,而无需主动轮询或等待。在回调中,
IsComplete
将始终为
true
,调用
WaitOne.Join
将始终立即返回

注意:在
AddComplete
回调中,您应该调用
EndInvoke
,而不仅仅是设置同步标志


因此,如果您的用例是
while
循环(“旋转等待”),您应该轮询
IsComplete
标志。另外两个用于其他情况。

你能举一个其他情况的例子吗。当我学习这个概念时会很有帮助。示例在我的文本中:
WaitOne
用于等待完成而不浪费CPU资源(这通常是自旋等待),
callback
用于继续工作而不在单独的线程中等待完成(即不需要同步调用时)。