我有一个需要连接的服务,它通过如下操作将数据传递回:
public Guid UpdateEntities<T>(Action<EntitiesChangedResponse<T>> onResponse, IEnumerable<T> entities)
{
//Get some data
onResponse.Invoke(response);
{
现有代码将按如下方式调用服务:
Guid requestId = _productService.UpdateEntities<Product>(x => OnEntitiesUpdated(x), new List<Product> { updateProduct1, updateProduct2 });
回调将在未来的某个时候对结果产生影响:
private void OnEntitiesUpdated<T>(EntitiesChangedResponse<T> response)
{
//Do something with the result
}
我试图将其与基于任务的信号R集线器集成,因此需要将操作作为类型化任务返回,但我一辈子都不知道如何实现这一点(我对任务很陌生,所以请告诉我这是否愚蠢)。
它看起来像这样:
public Task<EntitiesChangedResponse<Product>> UpdateProducts(List<Product> products)
{
//Somehow wrap this in a task
Task<EntitiesChangedResponse<Product>> result = New Task<EntitiesChangedResponse<Product>>( call the product service );
return result;
}
感谢您的帮助。它伤了我的头。
要在"回调"API和基于任务的API之间架起桥梁,可以使用TaskCompletionSource
public Task<EntitiesChangedResponse<Product>> UpdateProducts(List<Product> products)
{
var tcs = new TaskCompletionSource<EntitiesChangedResponse<Product>>();
_productService.UpdateEntities<Product>(response => tcs.SetResult(response), new List<Product> { updateProduct1, updateProduct2 });
return tcs.Task;
}
让我们看看以下方法:
public Task<EntitiesChangedResponse<T>> UpdateEntities<T>(IEnumerable<T> entities)
{
var updateTask = Task.Run(()=>
{
//return data from this lambda expression
});
return updateTask;
}
这将启动并返回一个完成您工作的任务。
(如果你真的需要GUID,你可以返回一个Tuple或任何包含两者的DTO)。
你现在有几个选项来消耗这个任务,这里有一个:
private Task async UpdateEntitiesAsync<T>(IEnumerable<T> entities)
{
try
{
EntitiesChangedResponse<T> response = await UpdateEntities(entities);
//asynchronous callback implementation code can go here
}
catch(AggregateException ex)
{
//handle a thrown exception
}
}
注意:
1) 一旦任务完成,执行将继续超过"wait"语句,并将执行以下LOC。
2) 如果任务出现故障(抛出异常),那么经过等待块的LOC将不会执行,而是执行catch子句。
3) 调用UpdateEntitiesAsync方法不会阻止调用线程。一旦命中await语句,执行将立即返回给调用者。
4) 您也可以等待异步方法返回的任务,因为它(隐式地)返回一个任务,一旦该方法完全执行,该任务就会完成,如果需要的话,该方法本身就不可用。
或者,如果您并不真正关心该方法何时完成,则可以让该方法返回void。
5) 如果您没有在该方法中捕捉到异常,请知道从异步方法返回的任务将出错,并且必须在调用链的某个位置进行处理。
您可以通过等待任务、访问Exception属性或调用任务的Wait方法来完成此操作。
6) 方法名称中的Async后缀只是一种命名约定,应用该约定是为了让客户端代码了解该方法的异步特性。