Return 来自将结果传递给 Action<T> 参数的方法的任务<T>

Return a Task<T> from a method that passes its result to an Action<T> parameter

我有一个需要连接的服务,它通过这样的操作传回数据:

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 集线器集成,因此需要 return 将操作作为类型化任务,但我终究无法弄清楚如何实现这一点(我对任务很陌生,所以请告诉我这是否愚蠢)。

看起来像这样:

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;
}

感谢任何帮助。头好痛

要在 "callback" 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;
 }

这将启动,return这是一项完成您工作的任务。

(如果你真的需要 GUID,你可以 return 元组或任何包含两者的 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) 一旦任务完成,执行将继续通过 'await' 语句,并将执行以下 LOC。

2) 如果任务出错(抛出异常),经过 await 块的 LOC 将不会执行,而是执行 catch 子句。

3) 调用 UpdateEntitiesAsync 方法不会阻塞调用线程。一旦 await 语句被命中,立即执行 return 给调用者。

4) 您也可以从异步方法中等待任务 return,因为它(隐含地)return 是一个任务,一旦该方法完全执行,该任务就可以完成,从而使该方法可等待本身,如果出现这种需要。

或者,如果您真的不关心它何时完成,您可以让此方法 return 无效。

5) 如果您没有捕获此方法中的异常,请知道从异步方法 return 执行的任务将会出错,并且必须在调用链的上游某处进行处理。

您可以通过等待任务、访问异常 属性 或调用任务的 Wait 方法来完成此操作。

6) 方法名称中的 Async 后缀只是一种命名约定,应用后客户端代码可以了解该方法的异步性质。