2

私は現在、Microsoft.Bcl.Async と .NET 4.0 を使用して、VS 2012 で記述されたコードを VS 2010 で動作させようとしています。VS 2010 では、Async CTP (ver. 3) をインストールしました。 V S2012 で書かれたプロジェクトをコンパイルできます。

Async CTP パックを動作させるのにかなり苦労した後、VS 2012 と VS 2010 の両方でプロジェクトをコンパイルできるようになりました。

ただし、実行時のコードの動作にはいくつかの違いがあります。私が実行しているコードを以下に示します。

public class Fetcher
{
    public string RunTask()
    {
        Task<string> task = TaskEx.Run(() => RunTaskAsync());
        return task.Result;                       
    }

    public async Task<string> RunTaskAsync()
    {
        await TaskEx.Delay(1);
        return "Hello";
    }        
}

基本的に、私が持っているのは非同期メソッドであり、クライアントがメソッドの非同期バージョンまたは同期バージョンのいずれかを呼び出すことができるように、同期ラッパーが必要です。

問題: VS 2012 からコードを実行すると、両方のメソッドが結果 "Hello" を返し、さらに重要なことに、両方のメソッドが適切に終了します。ただし、VS 2010 からコードを実行する場合は、話が大きく異なります。async メソッドは意図したとおりに機能しますが、sync ラッパー メソッドは単にハングし、結果が生成されません。

私は TPL と async/wait の概念にかなり慣れていないので、ここで見られる動作を説明するのに苦労しています。Async CTP には、私が認識していない何らかの制限がありますか、それとも概念的に間違った方法でこれを行っていますか?

4

1 に答える 1

4

原則として、非同期メソッドの同期ラッパーは強くお勧めしませんResultこのアプローチを使用すると、デッドロックのリスクが発生します(ブログで説明しています)。また、Result例外をラップするため、エラー処理がより複雑になります。

だから、「やらないで」と言います。

Async CTP に関する限り、存在することが知られているバグが多数あります (さらに、公開されていないバグもいくつかあります)。そして、それらは修正される予定はありません。全員を VS2012 にアップグレードすることを強くお勧めします。

この特定の問題については、パフォーマンスに関連している可能性があります。たとえば、Task.Delay(1)ほぼ即時に完了するタスクを返すため、遅延の開始とawait、タスクが既に完了しているかどうかを確認する間に競合状態が発生します。したがって、公式でのパフォーマンスの向上がMicrosoft.Bcl.Async動作の違いを引き起こしている可能性があります。

于 2013-09-10T13:38:09.980 に答える