C# 使用Taskcompletion源创建无线程任务
我在TPL中碰到了一个叫做TaskCompletionSource的主题,这是创建任务的方法之一,它允许开发人员设置结果、异常等,从而使您能够更好地控制任务。下面是一个使用TaskCompletionSource的示例C# 使用Taskcompletion源创建无线程任务,c#,multithreading,task-parallel-library,C#,Multithreading,Task Parallel Library,我在TPL中碰到了一个叫做TaskCompletionSource的主题,这是创建任务的方法之一,它允许开发人员设置结果、异常等,从而使您能够更好地控制任务。下面是一个使用TaskCompletionSource的示例 public static Task<int> RunAsyncFunction(Func<int> sampleFunction) { if (sampleFunction == null) thro
public static Task<int> RunAsyncFunction(Func<int> sampleFunction)
{
if (sampleFunction == null)
throw new NullReferenceException("Method cannot be null");
var tcs = new TaskCompletionSource<int>();
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
int result = sampleFunction();
tcs.SetResult(result);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
});
return tcs.Task;
}
公共静态任务runasync函数(Func sampleFunction)
{
if(sampleFunction==null)
抛出新的NullReferenceException(“方法不能为null”);
var tcs=new TaskCompletionSource();
ThreadPool.QueueUserWorkItem(=>
{
尝试
{
int result=sampleFunction();
tcs.SetResult(结果);
}
捕获(例外情况除外)
{
tcs.SetException(ex);
}
});
返回tcs.Task;
}
但是,这不是真正的异步编程。它是使用多线程的异步编程。如何转换此示例以使其在单个线程而不是多个线程上运行?或者还有其他的例子吗?为了实现异步,它需要在将来独立完成一些容量。这通常通过以下两种方式之一实现:
- 通过套接字IO、文件IO、系统计时器等操作的回调(可能导致重新激活的某些外部源)
- 第二个线程(可能是排队的工作池线程,如示例中所示)
Task
确实没有任何必要或意义。但是,您仍然可以通过立即执行计算并立即设置结果来公开它——或者更简单地说:使用Task.FromResult
但是,您显示的代码实际上是异步的——或者更具体地说:您返回的任务是异步的。它也许不是最好的用例,但它本身并没有什么问题——只是您的整个方法可以大大简化为:
return Task.Run(sampleFunction);
委员会:
对要在线程池上运行的指定工作进行排队,并返回该工作的任务或任务句柄
通常,如果我使用的是TaskCompletionSource
,那是因为我编写的是基于IO回调的任务,而不是基于ThreadPool
的任务<代码>任务。运行
对于大多数任务来说都很好。要实现异步,它需要一些将来独立完成的容量。这通常通过以下两种方式之一实现:
- 通过套接字IO、文件IO、系统计时器等操作的回调(可能导致重新激活的某些外部源)
- 第二个线程(可能是排队的工作池线程,如示例中所示)
Task
确实没有任何必要或意义。但是,您仍然可以通过立即执行计算并立即设置结果来公开它——或者更简单地说:使用Task.FromResult
但是,您显示的代码实际上是异步的——或者更具体地说:您返回的任务是异步的。它也许不是最好的用例,但它本身并没有什么问题——只是您的整个方法可以大大简化为:
return Task.Run(sampleFunction);
委员会:
对要在线程池上运行的指定工作进行排队,并返回该工作的任务或任务句柄
通常,如果我使用的是TaskCompletionSource
,那是因为我编写的是基于IO回调的任务,而不是基于ThreadPool
的任务<代码>任务。运行
对于大多数情况都很好。任务完成源代码不会使代码异步。它是一个实用工具,可以让其他人异步等待您的操作
您的操作本身需要是异步的。例如,如果它在一个较旧的范例中,比如BeginXXX/EndXXX
TaskCompletionSource主要用于将不同类型的异步编程转换为基于任务的异步编程 TaskCompletionSource不会使代码异步。它是一个实用工具,可以让其他人异步等待您的操作 您的操作本身需要是异步的。例如,如果它在一个较旧的范例中,比如BeginXXX/EndXXX
TaskCompletionSource主要用于将不同类型的异步编程转换为基于任务的异步编程 如果您有BeginXXX/EndXXX,您可以使用microsoft的utility methods@Gusdor sure包装该方法,因为它很常见。关键是,如果你需要实现这个方法,你可以使用TaskCuleTythOntRead。考虑我的评论,一个不知道的补充:-当然是Gusdor。如果愿意,您也可以在中编辑它。如果您有BeginXXX/EndXXX,您可以使用microsoft的utility methods@Gusdor sure包装该方法,因为它很常见。关键是,如果你需要实现这个方法,你可以使用TaskCuleTythOntRead。考虑我的评论,一个不知道的补充:-当然是Gusdor。如果愿意,您也可以在中编辑它。嗨,马克……那么TaskCompletionSource是创建无线程基本任务的唯一方法吗?@kyle在实现级别,是的;但是,如果您正在谈论的对象已经有了基于
任务的异步API,那么您通常可以使用异步/等待
通过延续来组成更复杂的逻辑;然后编译器会为您提供大部分细节。嗨,马克……那么TaskCompletionSource是创建无线程基本任务的唯一方法吗?@kyle在实现级别,是的;但是,如果您正在谈论的对象已经有了基于任务的异步API,那么您通常可以使用异步/等待
通过延续来组成更复杂的逻辑;然后,编译器将为您提供大部分详细信息。