<T> 从将其结果传递给 Action 参数的方法返回任务<T>



我有一个需要连接的服务,它通过如下操作将数据传递回:

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后缀只是一种命名约定,应用该约定是为了让客户端代码了解该方法的异步特性。

最新更新