1

コンパイルできない次のコードがあります。エラーが発生します

匿名メソッド、ラムダ式、またはクエリ式内で ref または out パラメーター 'messageLockToken' を使用することはできません

私はラムダが初めてで、これを解決するのに少し混乱していることを認めます。以下のロジックをコンパイラーが受け入れられる方法で表現する方法を知っている人はいますか?

public T Receive<T>(TimeSpan receiveTimeout, out Guid messageLockToken)
{
    // do work
}

public Task<T> ReceiveAsync<T>(TimeSpan receiveTimeout, out Guid messageLockToken)
{
    Task<T> sendQueueMsgTask = new Task<T>(() => Receive<T>(receiveTimeout, out messageLockToken));
    return sendQueueMsgTask;
}
4

2 に答える 2

1

まず、コンパイルしてもメソッドが機能しません。これはnew Task()、 を使用するときは、常にそれを呼び出すStart()(Taskまたは、代わりに を使用するTask.Run()) 必要があるためです。

outあまり意味がないので、ここではパラメーターを使用できません。メソッドから をすぐに返したいのですTaskが、それはすぐに を返すことも意味しGuidます。つまり、呼び出しがReceive()実際にoutパラメーターの値に影響を与える方法はありません。

Tuple(ローリングが提案したように)またはカスタムの戻り値の型を使用することがここに行く方法だと思います:

public Task<Tuple<T, Guid>> ReceiveAsync<T>(TimeSpan receiveTimeout)
{
    return Task.Run(
        () =>
        {
            Guid messageLockToken;
            var result = Receive<T>(receiveTimeout, out messageLockToken);
            return Tuple.Create(result, messageLockToken);
        });
}

これは、あなたが実際にこれをやりたいと思っていることを前提としています。 Stephen Toub の記事「同期メソッドの非同期ラッパーを公開する必要がありますか?」これを行うことがおそらく良い考えではない理由からです。

于 2012-12-18T12:51:18.997 に答える
0

ここではパラメーターを使用できないためout、代わりに次のことができます。

  • を返すTuple<T, Guid>(またはカスタム ジェネリック クラスを使用する)、または
  • Action<Guid>ではなくを渡しますout Guid(つまり、ReceiveAsync(ts, out myGuid)を呼び出すのではなくReceiveAsync(ts, g => myGuid = g))

(これを回避してoutパラメーターを呼び出し元に公開する方法はないと思います。outメソッドが返されるときにパラメーターが設定されるはずですが、これはあなたの場合には当てはまりません。)

于 2012-12-18T08:25:18.360 に答える