2009-11-23 152 views
3

实际上,我很难理解BeginInvoke()和EndInvoke()对。C#异步操作

class AsynchronousDemo 
{ 

    public delegate void DemoDelegate(); 
    static void Main() 
    { 

     DemoDelegate d = PrintA; 

     IAsyncResult AResult = d.BeginInvoke(Callback,null); 
     d.EndInvoke(AResult); 
     Console.ReadKey(true); 
    } 

    static void PrintA() 
    { 
     Console.WriteLine("....Method in Print A Running ...."); 
     Thread.Sleep(4000); 
     Console.WriteLine("....Method in Print A Completed..."); 
    } 


    static void Callback(IAsyncResult ar) 
    { 
     Console.WriteLine("I will be finished after method A 
     completes its execution"); 
    } 
} 

1)我们用 “的EndInvoke()” 来表示的BeginInvoke的结束 “异步操作”()..?

2)这些对的真正用途是什么?

3)我可以得到一些简单而好的例子来更好地理解它吗?

回答

10

想象一下,你有一个长期的任务要做,而且一次只能做一件事。通常情况下,为了做到这一点,你必须停止做其他事情。

// pseudocode 
Main() { 
    DoLaundry() 
    GoAboutYourDay() 
} 

DoLaundry() { 
    // boring parts here 
} 

现在想象一下,当洗衣服正在制作时,你希望能够度过你的一天。一种解决办法是让别人去做。所以你把它带到一家清洁商店,告诉他们该做什么,给他们穿衣服,告诉他们在完成时给你打电话。作为回报,他们会给你一张票,让他们在你想要他们时可以再次找到你的衣服。

// pseudocode 
Main() { 
    ticket = DoLaundry.BeginDoing(CallMeWhenDone) 
    GoAboutYourDay() 
    ticket.WaitUntilDone() 
} 

CallMeWhenDone(ticket) { 
    cleanLaundry = DoLaundry.FinishDoing(ticket) 
} 

这就是异步操作的工作原理。

的BeginInvoke你告诉程序,你需要做的工作(委托)是什么,当它这样做(回调)叫什么,做什么用(州)做到这一点。你得到一个IAsyncResult,它是你需要将它返回以便接收结果的对象。然后你可以做其他的事情,或者使用IAsyncResult中的WaitHandle来阻塞,直到操作完成。

回调:当异步操作完成时,它将调用此方法,为您提供与以前相同的IAsyncResult。此时,您可以从中检索您的状态对象,或将IAsyncResult传递给EndInvoke。

EndInvoke:该函数使用IAsyncResult并查找操作的结果。如果它还没有完成,它会阻塞直到它结束,这就是为什么你通常在回调中调用它的原因。

这是一个遍布整个框架的模式,而不仅仅是函数委托。像数据库连接,套接字等等,都经常有Begin/End对。

MSDN对这里的模式文档:http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx

+0

优秀explanation.would是非常有用的像我这样的初学者。 – user215675 2009-11-23 16:14:39

1

BeginInvoke正在启动一个异步操作EndInvoke正在等待该函数结束并返回结果。这是在C#中执行线程的另一种方式,其优点是begininvoke从线程池中取出线程,这对于Thread类是不正确的,另一个方法是可以更简单的方式传递参数并将结果传递给线程函数。这里有一个例子http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html

1

我不知道该如何解释不够好,但这篇文章应该有所帮助:
Asynchronous Programming Using Delegates MSDN上

摘录:
........... ..如果BeginInvoke方法被调用,公共语言运行库(CLR)将请求排队并立即返回给调用者。目标方法在线程池的线程上异步调用。提交请求的原始线程可以自由地继续与目标方法并行执行。如果在调用BeginInvoke方法时指定了回调方法,则在目标方法结束时调用回调方法。在回调方法中,EndInvoke方法获取返回值和任何输入/输出或仅输出参数。如果在调用BeginInvoke的时没有指定回调方法,EndInvoke会可以从所谓的的BeginInvoke的线程调用.....

1)我们用“的EndInvoke()”来表示结束“异步操作“的BeginInvoke()..?
不,你用它来获取返回值或...见上

2)什么是真正使用那些对?
所以,你可以在一个同步的方法等

3)我可以得到一些简单的和很好的例子更正确地理解它使异步调用?
我敢肯定,谷歌可以做到这一点比我更好:P

1

我用的是调用开始/结束调用构造运行窗口的服务。

例如:

public ServiceName() 
    { 
     //constructor code goes here 
    } 

    protected override void OnStart(string[] args) 
    { 
     ExecuteDelegate ed = new ExecuteDelegate(Execute); 
     AsyncCallback ac = new AsyncCallback(EndExecution); 
     IAsyncResult ar = ed.BeginInvoke(ac, ed); 
     Log.WriteEntry("Service has started."); 
    } 

    protected void EndExecution(IAsyncResult ar) 
    { 
     ExecuteDelegate ed = (ExecuteDelegate)ar.AsyncState; 
     ed.EndInvoke(ar); 
     Stop(); 
     Log.WriteEntry("Service has stopped."); 
    } 

    protected void Execute() 
    { 
     //Code goes here 
     ... 
    } 

    protected override void OnStop() 
    { 
     Log.WriteEntry("Service has stopped."); 
    } 

本质:调用BeginInvoke在一个新的线程启动的方法执行。当线程结束时,线程加入时调用的方法应该调用EndInvoke。