Asynchronous TaskCompletionSource-尝试了解无线程异步工作
我试图理解Asynchronous TaskCompletionSource-尝试了解无线程异步工作,asynchronous,task-parallel-library,Asynchronous,Task Parallel Library,我试图理解TaskCompletionSource的目的及其与异步/无线程工作的关系。我想我有大致的想法,但我想确保我的理解是正确的 我首先开始研究任务并行库(TPL),想知道是否有一种好方法可以创建自己的无线程/异步工作(比如说,您正试图提高ASP.NET站点的可伸缩性),另外,对TPL的理解看起来在未来非常重要(async/wait)。这让我找到了TaskCompletionSource 从我的理解来看,将TaskCompletionSource添加到一个类中并不像使编码异步那样有效;如果您
TaskCompletionSource
的目的及其与异步/无线程工作的关系。我想我有大致的想法,但我想确保我的理解是正确的
我首先开始研究任务并行库(TPL),想知道是否有一种好方法可以创建自己的无线程/异步工作(比如说,您正试图提高ASP.NET站点的可伸缩性),另外,对TPL的理解看起来在未来非常重要(
async
/wait
)。这让我找到了TaskCompletionSource
从我的理解来看,将
TaskCompletionSource
添加到一个类中并不像使编码异步那样有效;如果您仍在执行同步代码,则对代码的调用将被阻止。我认为这甚至适用于微软的API。例如,假设在WebClient
类的downloadstringtasksync
off中,他们最初执行的任何设置/同步代码都将被阻止。您正在执行的代码必须在某个线程上运行,或者在当前线程上运行,或者必须派生一个新线程
因此,当您从Microsoft调用其他
async
调用时,您可以在自己的代码中使用TaskCompletionSource
,这样您的类的客户端就不必为您的类创建一个新线程来阻止它
不确定微软如何在内部实现他们的异步API。例如,在.NET4.5的SqlDataReader
中有一个新的async
方法。我知道有IO完成端口。我认为这是一个较低级别的抽象(C++?),大多数C#开发人员可能不会使用。不确定IO完成端口是否适用于数据库或网络调用(HTTP),或者是否仅用于文件IO
所以问题是,我的理解正确吗?是否有某些东西我表示不正确?
TaskCompletionSource
用于创建不执行代码的Task
对象
微软新的异步API经常使用它们——任何时候都有基于I/O的异步操作(或其他非基于CPU的异步操作,如超时)。此外,您编写的任何异步任务
方法都将使用TCS来完成返回的任务
我有一篇博文讨论了创建Task
实例的不同方法。它是从async
/await
透视图(不是TPL透视图)编写的,但它仍然适用于这里
另请参见Stephen Toub的精彩帖子:
- (使用
到TaskCompletionSource
anything)wait
- (使用
创建TaskCompletionSource
/Begin
)End
- 我喜欢中提供的解释
(抱歉,该链接目前可能已断开)
前两段如下
我们已经了解了Task.Run如何创建一个在服务器上运行委托的任务
池(或非池)线程。创建任务的另一种方法是使用
TaskCompletionSource
TaskCompletionSource允许您通过执行以下操作来创建任务:
一段时间后开始和结束。它的工作原理是给你一个“奴隶”
通过指示操作完成的时间手动驱动的任务
或错误。这是I/O绑定工作的理想选择:您将获得所有好处
任务(具有传播返回值、异常、,
和continuations),而不会在
手术
要使用TaskCompletionSource,只需实例化该类。信息技术
公开一个任务属性,该属性返回可等待的任务
并像处理任何其他任务一样附加continuations。任务,,
但是,完全由TaskCompletionSource对象通过
以下方法:
公共类TaskCompletionSource
{
公共无效设置结果(TResult结果);
公共无效设置例外(例外);
公共无效设置已取消();
公共bool TrySetResult(TResult结果);
公共bool TrySetException(异常);
公共bool TrySetCanceled();
...
}
调用这些方法中的任何一个都会向任务发出信号,并将其放入
完成、故障或取消状态(我们将在
“取消”一节)。你应该调用其中一种方法
仅一次:如果再次调用,则SetResult、SetException或setCancelled
将引发异常,而Try*方法返回false
以下示例在等待五秒钟后打印42:
var tcs=new TaskCompletionSource();
新线程(()=>{
睡眠(5000);
tcs.SetResult(42);
})
.Start();
Task Task=tcs.Task;//我们的“奴隶”任务。
Console.WriteLine(task.Result);//42
其他有趣的引语
TaskCompletionSource的真正威力在于创建不需要的任务
把线捆起来
。。后来
在没有线程的情况下使用TaskCompletionSource意味着
仅当连续性开始时(5秒后)才接通。我们
可以通过一次启动10000个这样的操作来证明这一点
没有错误或过度的资源消耗:
如果我的理解是正确的…不确定是否正确,但我对内部的理解是否正确?任何异步方法(当然)都有一个用于启动异步操作的同步部分。IIRC,IOCP可用于任何类型的基于
句柄的数据传输,并且(今天)将IOCP操作包装在开始
/结束
中,并将其包装在任务
中的异步
方法中(使用任务完成源
)并不少见.我也在努力了解Ta的用法
public class TaskCompletionSource<TResult>
{
public void SetResult(TResult result);
public void SetException (Exception exception);
public void SetCanceled();
public bool TrySetResult (TResult result);
public bool TrySetException (Exception exception);
public bool TrySetCanceled();
...
}
var tcs = new TaskCompletionSource<int>();
new Thread (() => {
Thread.Sleep (5000);
tcs.SetResult (42);
})
.Start();
Task<int> task = tcs.Task; // Our "slave" task.
Console.WriteLine(task.Result); // 42