简体   繁体   English

异步方法和异步委托

[英]Asynchronous methods and asynchronous delegates

C# 3.0 in a nutshell says asynchronous methods and asynchronous delegates looks similar but the behavior is very different. 简而言之,C#3.0异步方法异步委托看起来很相似,但行为却截然不同。

Here is what the book says about both. 这是本书所说的两者。

Asynchronous methods 异步方法

  1. Rarely or never blocks any thread. 很少或从不阻止任何线程。
  2. Begin method may not immediately return to the caller. Begin方法可能不会立即返回给调用者。
  3. An agreed protocol with no C# language support. 一个没有C#语言支持的商定协议。

Asynchronous delegates 异步代理

  1. May block for any length of time 可以阻止任何时间长度
  2. BeginInvoke return immediately to the caller. BeginInvoke立即返回给调用者。
  3. Built-in compiler support. 内置编译器支持。

The book also says, The purpose of asynchronous methods is to allow many tasks to run on few threads; 该书还说, 异步方法的目的是允许许多任务在少数线程上运行; the purpose of asynchronous delegates is to execute a task in parallel with the caller . 异步委托的目的是与调用者并行执行任务

When I looked into the BeginRead() method in System.IO.Stream class through reflector, it is using a delegate and calling BeginInvoke on that. 当我通过反射器查看System.IO.Stream类中的BeginRead()方法时,它正在使用委托并在其上调用BeginInvoke So an asynchronous method is using an asynchronous delegate internally. 因此异步方法在内部使用异步委托。

  1. In such case, how can one say their behaviors are different? 在这种情况下,怎么能说他们的行为不同? Since it uses delegates internally, how a comparison like the above is possible? 既然它在内部使用委托,那么如何进行上述比较呢?
  2. Do you think working with a delegate's BeginXXX method is the way to execute a function in parallel to the caller? 您是否认为使用委托的BeginXXX方法是与调用者并行执行函数的方法?
  3. What is the proper way to implement asynchronous methods by maintaining all the advantages like making good use of CPU? 通过保持充分利用CPU等所有优点来实现异步方法的正确方法是什么?

Any thoughts? 有什么想法吗?

At the core, there are two main behaviors you may see when you call BeginFoo() with a callback. 在核心,当您使用回调调用BeginFoo()时,您可能会看到两个主要行为。

  1. Work is started on a background thread, and that thread will be used the entire time up until the work is completed and the callback is invoked (eg because the work is synchronous). 工作在后台线程上启动,该线程将一直使用,直到工作完成并调用回调(例如因为工作是同步的)。
  2. Though some work happens on a background thread, the thread need not be in use the entire time (eg because the work involves System IO which can schedule callbacks on eg the IOCompletionPort). 虽然某些工作在后台线程上发生,但线程不需要在整个时间内使用(例如,因为工作涉及可以在例如IOCompletionPort上调度回调的系统IO)。

When you use a delegate, behavior #1 above happens. 当您使用委托时,会发生上述行为#1。

Some APIs (that have underlying support for non-blocking IO calls) support behavior #2. 某些API(具有对非阻塞IO调用的底层支持)支持行为#2。

In the specific case of 'Stream', I am not sure, but my guess is it is an abstract base class and so this is merely the default behavior for a subclass that implements only a synchronous version of Read. 在'Stream'的特定情况下,我不确定,但我的猜测是它是一个抽象基类,所以这只是一个只实现Read同步版本的子类的默认行为。 A 'good' subclass would override BeginRead/EndRead to have a non-blocking implementation. 'good'子类将覆盖BeginRead / EndRead以具有非阻塞实现。

The advantage of #2, as you said, is that you can have eg 100 pending IO calls without consuming 100 threads (threads are expensive). 正如你所说,#2的优势在于你可以拥有100个待处理的IO调用而不需要消耗100个线程(线程很昂贵)。

  1. The implementation can be different; 实施可能不同; for example, an async IO call may choose to make use of completion ports to minimise the cost to the system while not doing anything. 例如,异步IO调用可以选择使用完成端口来最小化系统成本而不执行任何操作。
  2. It is certainly a way; 这当然是一种方式; you could also use BackgroundWorker , ThreadPool.QueueUserWorkItem , or Parallel.For (etc) in .NET 4.0 你也可以在.NET 4.0中使用BackgroundWorkerThreadPool.QueueUserWorkItemParallel.For (etc)
  3. Varies per implementation 每个实施都有所不同

I think what the book is trying to highlight is that delegates always include this pattern: 我想这本书试图强调的是代表们总是包含这种模式:

  • a synchronous call ( Invoke ) that can block 可以阻止的同步调用( Invoke
  • an async call ( BeginInvoke ) that shouldn't really block unless the thread-pool is saturated 除非线程池已饱和,否则不应该真正阻塞的异步调用( BeginInvoke

but it isn't the only pattern. 但它不是唯一的模式。 Also; 也; more recently (for example, the async IO methods in Silverlight, or in WebClient ): rather than an IAsyncResult , an event is used to signal completion. 最近(例如,Silverlight或WebClient的异步IO方法):而不是IAsyncResult ,事件用于表示完成。

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

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