web-dev-qa-db-ja.com

待機または戻りのないC#非同期タスクメソッド

次のような2つの場所に実装されているインターフェイスIがあります。

interface I 
{ 
   Task DoSomething();
}

インターフェースには、次のようにクラスAに実装される非同期タスクDoSomethingメソッドAPIがあります。

class A : I {....}

class B : I {....}

クラスAでは、DoSomethingの実装は次のようになり、それで問題ありません。

public async Task DoSomething()
{
    if (...)
    {
        await DoIt();
    }
}

ただし、クラスBでは、DoSomething()の実装は何も実行しません。そのため、その実装は次のようになります。

public async Task DoSomething()
{
    // nothing
}

これはコンパイルされますが、メソッドが役に立たないという事実のほかに、これがどのように正しいかはわかりません。

しかし、この場合は、インターフェイスIを実装するクラスBによって必要とされるという理由だけで実装されているため、この場合「役に立たない」ことは問題ありません。

これは非同期タスクを返すが待機も戻りもしないメソッドを実装する正しい方法だろうか?このメソッドは、待機する呼び出しがないため、単純に何もせずに同期的に実行されることを知っています。

更新:ここでSOで同様の質問がされており、これを尋ねる前にすべての質問を確認しました。

10
pixel
public Task DoSomething()
{
    return Task.CompletedTask;
}

asyncは必要ありません。

古いバージョンの.NETを使用している場合、これを使用します。

public Task DoSomething()
{
    return Task.FromResult(0);
}

結果を返す必要があるが、まだawait何もする必要がない場合は、試してください。

public Task<Result> DoSomething()
{
    Task.FromResult(new Result())
}

または、本当に非同期を使用する場合(推奨されません)。

public async Task<Result> DoSomething()
{
    return new Result();
}
28
sellotape

ほとんどの人はasyncを省き、代わりに_Task.ComletedTask_を使用することを好みます。ただし、awaitを使用しない場合でも、例外処理には大きな違いがあります。

次の例を考えてください

_static async Task Main(string[] args)
{

    Task task = test(); // Will throw exception here
    await task;

    Task taskAsync = testWithAsync();
    await taskAsync; // Will throw exception here
}

static Task test()
{
    throw new Exception();
    return Task.CompletedTask; //Unreachable, but left in for the example
}

static async Task testWithAsync()
{
    throw new Exception();
}
_

を使用して

test().ContinueWith(...);またはTask.WhenAll(test())

予期しない動作が発生する可能性があります。

したがって、私は_Task.CompletedTask_または_Task.FromResult_ではなくasyncを好みます。

0
Jan-Fokke