web-dev-qa-db-ja.com

タスクベースの非同期メソッドのコールバックを定義する場所

この質問 に従って、TPLを使用して非同期メソッドを実装し、TAPガイドラインに従うようにしています。

非同期メソッドが終了したときにコールバックを実行するようにします。私が見る限り、これを行うには3つの方法があります。

1)タスクデリゲートで手動でコールバック

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

        //call callback manually
        completedCallback();
    });
}

2)タスクデリゲートでタスクにコールバックを割り当てます

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

3)呼び出し元のタスクにコールバックを割り当てる

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

public void SomeClientCode()
{
    Task doingWork = DoWorkAsync();
    doingWork.ContinueWith(OnWorkCompleted);
}

私の直感では、3はメソッドからコールバックを切り離し、クライアントコードがタスクを適切に管理できることを意味します(コールバック、ポーリングなどを使用)。 。ただし、クライアントコードがコールバックをフックする前にDoWorkAsync()が作業を完了するとどうなりますか?

これを行う一般的に受け入れられている方法はありますか、それともまったく新しいですか?

1)よりも2)を行う利点はありますか?

44
GazTheDestroyer

一般的に受け入れられている方法は3です。

TPLのユーザーは通常、ContinueWithでタスクを続行できることを知っています。 1と2は同じ機能を提供しますが、非標準インターフェースを備えています。ユーザーは、デリゲートパラメーターの意味と渡すものを把握する必要があります。継続したくない場合-メソッドは、標準の方法で継続できるタスクを返します。

33
dtb