繁体   English   中英

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

[英]Using 'out' within lambdas when creating Tasks via 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;
}

首先,即使已编译,您的方法也无法使用。 这是因为当您使用new Task() ,始终必须在该Task上调用Start() (或者使用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的文章我应该为异步方法公开异步包装器吗? 由于某些原因,这样做可能不是一个好主意。

由于您不能在此处使用out参数,因此可以:

  • 返回Tuple<T, Guid> (或使用自定义的通用类),或
  • 传递一个Action<Guid>而不是out Guid (因此ReceiveAsync(ts, out myGuid)您将调用ReceiveAsync(ts, g => myGuid = g)而不是ReceiveAsync(ts, out myGuid) ReceiveAsync(ts, g => myGuid = g)

(我认为您没有任何方法可以解决此问题,仍然向调用方公开out参数;应该在该方法返回时填充out参数,但是在您的情况下情况并非如此。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM