简体   繁体   English

C#异步操作

[英]C# Asynchronous operation

Acctually I have hardtime in understanding BeginInvoke() and EndInvoke() pair. 实际上,我很难理解BeginInvoke()和EndInvoke()对。

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) Do we use "EndInvoke()" to indicate the ending "asynchronous operation" of BeginInvoke()..? 1)我们使用“EndInvoke()”来表示BeginInvoke()的结束“异步操作”吗?

2) What is the real use of those pair? 2)这对配对的实际用途是什么?

3) can i get some simple and nice examples to understand it more properly? 3)我可以得到一些简单而好的例子来更恰当地理解它吗?

Imagine you have a long task to do, and can only do one thing at a time. 想象一下,你有很长的任务要做,而且一次只能做一件事。 Normally, in order to do it, you'd have to stop doing everything else. 通常,为了做到这一点,你必须停止做其他事情。

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

DoLaundry() {
    // boring parts here
}

Now imagine you want to be able to go about your day while your laundry is being made. 现在想象一下,您希望能够在洗衣服的同时度过一天。 One solution would be to get someone else to do it. 一种解决方案是让别人去做。 So you take it to a cleaning shop, tell them what to do, give them your clothes, and tell them to phone you when they're done. 所以你把它带到一家清洁店,告诉他们该做什么,给他们你的衣服,并告诉他们完成后给你打电话。 In return, they give you back a ticket so they can find your clothes again when you want them back. 作为回报,他们会给你一张票,这样他们可以在你想要的时候再找到你的衣服。

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

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

This is how asynchronous operation works. 这是异步操作的工作原理。

BeginInvoke You tell the program what you need to be done (the delegate), what to call when it's done (callback), and what to do it with (state). BeginInvoke你告诉程序你需要做什么(委托),什么时候完成调用(回调),以及用什么来做(状态)。 You get back an IAsyncResult, which is the object that you need to give it back in order to receive your result. 您将返回IAsyncResult,这是您需要将其返回以便接收结果的对象。 You can then do other stuff, or use the WaitHandle in the IAsyncResult to block until the operation's done. 然后,您可以执行其他操作,或使用IAsyncResult中的WaitHandle进行阻止,直到操作完成。

Callback: When the asynchronous operation finishes, it will call this method, giving you the same IAsyncResult as before. 回调:当异步操作完成时,它将调用此方法,为您提供与以前相同的IAsyncResult。 At this point, you can retrieve your state object from it, or pass the IAsyncResult to EndInvoke. 此时,您可以从中检索状态对象,或将IAsyncResult传递给EndInvoke。

EndInvoke: This function takes the IAsyncResult and finds the result of the operation. EndInvoke:此函数接受IAsyncResult并查找操作的结果。 If it hasn't finished yet, it'll block until it does, which is why you usually call it inside the callback. 如果还没有完成,它会阻塞直到它完成,这就是你通常在回调中调用它的原因。

This is a pattern that's often used all over the framework, not just on function delegates. 这是一种经常在整个框架中使用的模式,而不仅仅是函数委托。 Things like database connections, sockets, etc. all often have Begin/End pairs. 数据库连接,套接字等都经常有Begin / End对。

MSDN has documentation on the pattern here: http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx MSDN上有关于模式的文档: http//msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx

BeginInvoke is starting an Asynchronous operation EndInvoke is waiting to the end of that function and returning result. BeginInvoke正在启动异步操作EndInvoke正在等待该函数的结束并返回结果。 it's an another way to execute threading in C#, the great features are that begininvoke take the thread fromm thread pool, which is not correct for Thread class, and another one is that you can pass parameters and get result to thread function in more easy way. 这是在C#中执行线程的另一种方式,很棒的功能是begininvoke从线程池获取线程,这对于Thread类是不正确的,另一个是你可以以更简单的方式传递参数并获得结果到线程函数。 here is an example http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html 这是一个例子http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html

I don't know how to explain it well enough but this article should help: 我不知道如何解释得很好,但这篇文章应该有所帮助:
Asynchronous Programming Using Delegates on MSDN 在MSDN上使用代理进行异步编程

Excerpt: 摘抄:
.............If the BeginInvoke method is called, the common language runtime (CLR) queues the request and returns immediately to the caller. .............如果调用BeginInvoke方法,公共语言运行库(CLR)将请求排队并立即返回给调用者。 The target method is called asynchronously on a thread from the thread pool. 目标方法在线程池的线程上异步调用。 The original thread, which submitted the request, is free to continue executing in parallel with the target method. 提交请求的原始线程可以自由地继续与目标方法并行执行。 If a callback method has been specified in the call to the BeginInvoke method, the callback method is called when the target method ends. 如果在对BeginInvoke方法的调用中指定了回调方法,则在目标方法结束时调用回调方法。 In the callback method, the EndInvoke method obtains the return value and any input/output or output-only parameters. 在回调方法中, EndInvoke方法获取返回值以及任何输入/输出或仅输出参数。 If no callback method is specified when calling BeginInvoke , EndInvoke can be called from the thread that called BeginInvoke ..... 如果在调用BeginInvoke时没有指定回调方法,则可以从调用BeginInvoke的线程调用EndInvoke .....

1) Do we use "EndInvoke()" to indicate the ending "asynchronous operation" of BeginInvoke()..? 1)我们使用“EndInvoke()”来表示BeginInvoke()的结束“异步操作”吗?
No, you use that to obtain the return values or... see above 不,您使用它来获取返回值或...见上文

2) What is the real use of those pair? 2)这对配对的实际用途是什么?
So you can make asynchronous call on a synchronous method etc 因此,您可以在同步方法等上进行异步调用

3) can i get some simple and nice examples to understand it more properly? 3)我可以得到一些简单而好的例子来更恰当地理解它吗?
I'm pretty sure google can do this better than me :P 我很确定谷歌可以做得比我好:P

I use the Begin Invoke / End Invoke construct to run Window's services. 我使用Begin Invoke / End Invoke构造来运行Window的服务。

For example: 例如:

    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.");
    }

Essentially: Call BeginInvoke to start execution of a method in a new thread. 本质上:调用BeginInvoke以开始在新线程中执行方法。 When the thread is over then the method that is called when the thread is joined should call EndInvoke. 当线程结束时,线程连接时调用的方法应该调用EndInvoke。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM