gpt4 book ai didi

c# - 使用 async/await 时使用未分配的局部变量

转载 作者:太空宇宙 更新时间:2023-11-03 17:31:40 24 4
gpt4 key购买 nike

此代码在没有 await 的情况下编译:

IEnumerable<PingResponse> pingResponses;
using (var prestoWcf = new PrestoWcf<IPingService>())
{
pingResponses = prestoWcf.Service.GetAllForPingRequest(this.PingRequest);
}

foreach (PingResponse response in pingResponses) { // code here }

此代码带有await,无法编译:

IEnumerable<PingResponse> pingResponses;
await Task.Factory.StartNew(() =>
{
using (var prestoWcf = new PrestoWcf<IPingService>())
{
pingResponses = prestoWcf.Service.GetAllForPingRequest(this.PingRequest);
}
});

foreach (PingResponse response in pingResponses) { // code here }

错误是:Use of unassigned local variable 'pingResponses'

为什么引入 async/await 会导致这个问题?

最佳答案

它不起作用的原因是编译器无法知道提供给 StartNew 方法的委托(delegate)将始终在您的 foreach 循环之前执行。你知道,我也知道,但是编译器无法证明它是当前明确的可分配性规则。

虽然有几种“解决方法”可以欺骗编译器让您这样做,但最好和最惯用的解决方案是让任务返回一个结果,而不是改变一个封闭的变量.这样你就不会依赖任务的副作用,而是依赖结果本身。这使得代码更容易推理(任务和使用它的代码可以单独分析,而不是让每个依赖于另一个的实现)并确保不同线程之间共享内存的正确同步(一项重要的任务) .

至于具体的代码,在dcastro's answer中已经给出了:

IEnumerable<PingResponse> pingResponses = 
await Task.Factory.StartNew(() =>
{
using (var prestoWcf = new PrestoWcf<IPingService>())
{
return prestoWcf.Service.GetAllForPingRequest(this.PingRequest);
}
});

更好的是,根据 SLack's suggestion您可以使用适当异步的方法,而不是在线程池线程中使用同步方法。这样做允许您利用操作系统的能力来通知您网络请求的完成,而不会浪费线程池的资源,因为线程池坐在那里无所事事。

关于c# - 使用 async/await 时使用未分配的局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19731600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com