1

我有以下无法编译的代码。我得到错误

不能在匿名方法、lambda 表达式或查询表达式中使用 ref 或 out 参数“messageLockToken”

我承认我是 Lambdas 的新手,对解决这个问题有点困惑。有谁知道我如何以编译器可接受的方式表达下面的逻辑?

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(如 Rawling 建议的)或自定义返回类型是这里的方法:

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 回答