14

私は非同期 CTP で手を汚そうとしていますが、コンパイラが非同期の戻り値の型について不平を言っていることに気付きました。他のタイプの問題点は何ですか?

簡単なデモ

static void Main(string[] args)
{
    DoWork();
    Console.WriteLine("Returned to main");
    Console.Read();
}

// why do I need to return void, Task or Task<T> here?
// I know I can use something like Task<IEnumerable<string>>
private static async string[] DoWork()
{
    Console.WriteLine("DoWork started");
    return await Task.Factory.StartNew(
        delegate
        {
            Thread.Sleep(2000);                
            Console.WriteLine("DoWork done");
            return new List<string>();
        });        
}
4

2 に答える 2

12

[消費] 側では、await柔軟です。適切なメソッドがある限り、どの型も待機できます。

asyncメソッド [プロダクション] 側では、柔軟性がありません。Task タイプ (または void) のみを返すようにハードコードされています。矛盾の理由は?

  1. イテレータにはすでにこの動作があります...

    イテレータ メソッド (内部に「yield」を持つメソッド) は、IEnumerable または IEnumerator のいずれかを返すようにハードコードされています。ただし、GetEnumerator/MoveNext/Current メンバーを持つ任意の型に対して "foreach" を実行できます。したがって、非同期はスイートに従っているだけです。

  2. タスクは未来のようなものなので、ハードコードするのは良いことです...

    タスクは未来以上のものではありません。未来は、言語/プラットフォームの基本的な部分です。そのような基本的な概念の複数のコピーを言語 2 が持つ理由はありません。1つで十分です。これは非常に基本的なものであり、未来を扱うために言語にキーワードを追加することさえあります。とにかく、誰かが未来のようなもの、またはより豊かなタスクの概念を持っている場合、彼らはそれを Task または Func から構築することができます。(私たちのタスクは既に実行されています。F# asyncs や IObservable のような「コールド」なものを構築したい場合は、指示するまで開始されません。仕事)。

  3. さらなる機微

    この関数を定義します。

    void f<T>(Func<Task<T>> f)
    

    そしてそれを呼び出します:

    f( () => 1 + await t )
    

    この場合、T=int であると推測できるようにしたいと考えています。このような推論は、コンパイラが "f" に渡すラムダの型が Task<int>.

出典: Async CTP の技術紹介

于 2011-08-10T12:47:44.113 に答える
8

aTask<TResult>は「未来」であるため、後で発生する値です。Astring[]はあなたが今持っているものです。

同様にTask、将来のある時点で (正常に終了するか、エラーが発生して) 完了する操作です。

void特殊なケースです。これは、非同期 CTP の最上位の操作を表します。

が自動的に推論されない理由が気になる場合はTask、これは考慮されましたが、Async CTP チームによって拒否されました。彼らの理論的根拠はここにあり、このスレッドもそれをカバーしています。

于 2011-08-10T12:43:59.047 に答える