52

アプリケーションがあります。このアプリケーションは、インターフェースを使用してデータベースにアクセスします。このインターフェースは、多くのクラスで実装できます。たとえば、1つはEF 4.4を使用しますが、他のクラスはより効率的なEF5を使用できます。将来的には、非同期メソッドを使用するEF6を使用する予定です。この例では、すべてのメソッドがEFを使用していますが、おそらく他のオプションを他の方法で使用することもできます。

アプリケーションはインターフェイスを使用して一度コーディングされ、構成ファイルに従って、いずれかの実装を使用するため、クラスのインスタンス化に新しいオプションを追加するために、コンストラクターという1つの場所でコードを変更するだけで済みます。それはインターフェースに割り当てられます。

現時点では、クラスのすべてのメソッドがそうではありませんasyncが、将来的にEF6を使用する場合は非同期メソッドを使用したいので、EF6を使用してインターフェイスを実装するクラスができるかどうかはわかりません。メソッドを使用しasyncます。

EF6の非同期メソッドでは、async / awiatパターンを使用するため、クラスのメソッドではasync属性を使用する必要があります。これによりawait、EF6のasyncメソッドを呼び出すときにキーワードを使用できます。

しかし、このクラスは、初めて同期メソッド用のインターフェイスを実装できますか?

メインアプリケーションで、コードを変更せずに多くの実装を使用できる方法はありますか?一部の実装は非同期メソッドを使用しますが、他の実装は同期メソッドを使用します。

4

1 に答える 1

64

asyncは署名の一部ではないため、インターフェイスを実装するメソッドがそうであるかどうかを実際に気にする必要はありませんasync。プロパティの型、戻り値の型、名前だけを気にする必要があります。メソッド、およびアクセシビリティ。

本当の違いは、メソッドが aまたは aasyncを返す必要があるのに対し、非非同期メソッドは現在または何らかの型を直接返す可能性が高いことです。TaskTask<T>voidT

アプリケーションを「将来的に保証」したい場合、1 つのオプションは、すべてのインターフェイスがTaskorTask<T>を返すようにすることです。また、EF4/EF5 の実装では、結果が同期的に実行されていても、完了したタスクにラップします。

Task.FromResult.NET 4.5 で追加されましたが、持っていない場合は、自分で簡単に作成できます。

public static Task<T> FromResult<T>(T result)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(result);
    return tcs.Task;
}

すでに完了したタスクを単純に返すメソッドを作成することもできCompletedTaskます (効率上の理由から、単一のタスクをキャッシュします)。

private static Task _completedTask;
public static Task CompletedTask()
{
    return _completedTask ?? initCompletedTask();
}

private static Task initCompletedTask()
{
    var tcs = new TaskCompletionSource<object>();
    tcs.SetResult(null);
    _completedTask = tcs.Task;
    return _completedTask;
}

これらの 2 つのメソッドは、すべてのメソッドが何らかの型の を返すプロセスを簡素化しますがTask、これを行うと、C# 5.0 を使用しawaitて結果を得ることができるようになるまで、コードが少し面倒になります。

于 2012-11-26T21:47:17.267 に答える