在通过任务并行库创建任务时在lambdas中使用'out'

时间:2012-12-18 03:16:48

标签: c# lambda task-parallel-library

我有以下不编译的代码。我收到了错误

  

不能在匿名方法,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;
}

2 个答案:

答案 0 :(得分:1)

首先,即使编译了你的方法也行不通。这是因为当您使用new Task()时,您始终必须在Start()上致电Task(或者使用Task.Run())。

现在,你不能在这里使用out参数,因为它没有多大意义。您希望立即从方法返回Task,但这也意味着立即返回Guid。这意味着您对[{1}}的调用无法实际影响Receive()参数的值。

我认为使用out(如Rawling建议的)或自定义返回类型是这里的方法:

Tuple

这假设您确实想要这样做,请参阅Stephen Toub的文章Should I expose asynchronous wrappers for synchronous methods?,了解为什么这样做可能不是一个好主意。

答案 1 :(得分:0)

由于您无法在此处使用out参数,您可以:

  • 返回Tuple<T, Guid>(或使用自定义通用类)或
  • 传递Action<Guid>而不是out Guid(而不是ReceiveAsync(ts, out myGuid)你打电话给ReceiveAsync(ts, g => myGuid = g)

(我认为有任何办法可以解决此问题仍然向调用者公开out参数;当方法返回时,应该填充out参数,但是在你的情况下不会是真的。)