在哪里定义基于任务的异步方法的回调

Gaz*_*yer 46 c# asynchronous callback task-parallel-library

这个问题之后,我试图使用TPL实现异步方法,并尝试遵循TAP指南.

我希望我的异步方法在完成后执行回调.据我所知,有三种方法可以做到这一点.

1)在我的任务委托中手动回调

public Task DoWorkAsync(DoWorkCompletedCallback completedCallback)
{
    return Task.Factory.StartNew(
    { 
        //do work

        //call callback manually
        completedCallback();
    });
}
Run Code Online (Sandbox Code Playgroud)

2)在任务委托中为任务分配回调

public Task DoWorkAsync(DoWorkCompletedCallback completedCallback)
{
    return Task.Factory.StartNew(
    { 
        //do work
    }
    ).ContinueWith(completedCallback); //assign callback to Task
}
Run Code Online (Sandbox Code Playgroud)

3)在呼叫者中为任务分配回叫

public Task DoWorkAsync()
{
    return Task.Factory.StartNew(
    { 
        //do work
    });
}

public void SomeClientCode()
{
    Task doingWork = DoWorkAsync();
    doingWork.ContinueWith(OnWorkCompleted);
}
Run Code Online (Sandbox Code Playgroud)

我的直觉是3更正确,因为它将回调与方法分离,并且意味着客户端代码可以以任何方式管理任务(使用回调,轮询等),这似乎是任务的全部内容.但是,如果DoWorkAsync()在客户端代码挂钩其回调之前完成其工作会发生什么?

是否有一种普遍接受的方式来做到这一点还是全新的?

做2)超过1)有什么好处吗?

dtb*_*dtb 33

普遍接受的方式是3.

TPL的用户通常知道他们可以使用ContinueWith继续任务.1和2提供相同的功能,但具有非标准接口; 用户必须弄清楚什么的委托参数意味着什么通过例如,如果他们不想继续 - 所有的,而方法又返回,可以以标准方式继续任务.

  • 谢谢,这是有道理的.将继续使用3.但是如果任务在连接继续委托之前完成会发生什么?它还会被调用吗?我发现文档有点模糊. (5认同)
  • 是的,它会被调用. (5认同)