![](/img/trans.png)
[英]Convert TaskCompletionSource to Task.FromResult<TResult>?
[英]Return Task instead of Task<TResult> from TaskCompletionSource
正如我在几个编码示例中看到的,以及从这个SO问题我可以理解的,我应该能够从TaskCompletionSource返回一个非泛型任务
(i.e., Return Task and not Task<TResult> from the method UploadFilesAsync)
但是以下代码:
public async Task UploadFilesAsync(string fileAPath, string fileBPath)
{
var tcs = new TaskCompletionSource<Object>();
//logic to process files
try
{
await Task.WhenAll(uploadFileAAsync(fileAPath),
uploadFileBAsync(fileBPath));
tcs.TrySetResult(null);
}
catch (Exception e)
{
tcs.SetException(e);
}
finally
{
//logic to clean up files
}
return tcs.Task;
}
产生以下语法错误
'UploadFilesAsync(string, string)' is an async method that returns 'Task',
a return keyword must not be followed by an object expression.
Did you intend to return 'Task<T>'?
我的目标是.NET 4.5。 我知道它可以返回Task(对象),但这会使API感觉“脏”。 是首选返回Task(对象)还是可以返回Task(非泛型,如代码所示)?
我知道它可以工作返回Task(对象)
那么,这不会达到你的预期。
麻烦的是你正在尝试返回一个任务......而异步方法会自动将返回值包装在另一个任务中。 说实话,目前还不清楚为什么你在这里使用异步方法。 为什么不写这个:
public Task UploadFilesAsync(string fileAPath, string fileBPath)
{
return Task.WhenAll(uploadFileAAsync(fileAPath), uploadFileBAsync(fileBPath));
}
那不是你想做的吗? 你只想要一个在两个“子操作”完成时完成的任务,对吧? 这正是Task.WhenAll
返回的内容。 您的方法仍然是非阻塞的 - 它不会等到操作完成后再返回。 只是你正在使用Task.WhenAll
是非阻塞的事实来实现它,而不是异步方法。
编辑:请注意,如果您想在该方法中执行其他操作,则可以在不使用TaskCompletionSource
情况下将其设置为异步方法:
public async Task UploadFilesAsync(string fileAPath, string fileBPath)
{
// Upload the files
await Task.WhenAll(uploadFileAAsync(fileAPath), uploadFileBAsync(fileBPath));
await SomethingElseAsync();
MaybeDoSomethingCheap();
}
请注意,即使此处的async方法返回Task
,您也没有返回值 - async / await机制为您处理所有这些,返回一个任务,该任务将在MaybeDoSomethingCheap()
完成时完成,或者如果异常则返回错误被扔了。
据我所知,在使用TaskCompletionSource<T>
时没有直接返回Task
对象的方法。
通常我更喜欢在这些情况下返回Task<bool>
类型对象。 但你是对的,如果函数的返回值不可用,则返回泛型类型对象是没有意义的。
但实际上你不需要创建一个TaskCompletionSource
因为你在函数中有一个await
关键字。 TaskCompletionSource
通常用于将同步函数转换为异步函数。 由于您已经在调用异步函数(实际上这似乎是唯一的功能),因此您无需创建TaskCompletionSource
。
public async Task UploadFilesAsync(string fileAPath, string fileBPath)
{
return await Task.WhenAll(uploadFileAAsync(fileAPath), uploadFileBAsync(fileBPath));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.