【问题标题】:Foreach after await等待后的 foreach
【发布时间】:2016-08-15 09:22:38
【问题描述】:

在等待调用后,我遇到了 foreach 循环的问题。 purchaseOrders 填充了 4 个订单,但 foreach 每次在达到 4 个迭代之前都会停止。执行停止,并且不会运行GetInvoices 调用。

GetPurchaseOrders("50000");
GetInvoices("10000");

static async void GetPurchaseOrders(string supplier)
{
    var purchaseOrders = await VNA.PurchaseOrders.ForSupplierAsyncTask(supplier);

    foreach (var order in purchaseOrders)
    {
        CreateXMLDocument(order, order.orderNbr, "PurchaseOrder");
    }
}

【问题讨论】:

  • 追踪告诉你什么?
  • CreateXMLDocument 是无效的吗?或者也许是一个异步方法?
  • 听起来像是在某个地方出现了死锁,您是否尝试添加ConfigureAwait
  • 您应该避免编写 async void 方法的众多原因之一 - 没有自然的地方可以捕获未处理的异常。
  • 如果你在 foreach 行中断,根据调试器,purchaseOrders 的内容是什么?有四个命令吗? ForSupplierAsyncTask 的返回值是多少?它是一个 IEnumerable 可能会使用延迟执行吗?您确定 ForSupplierAsyncTask 使用 ToList() 或 ToArray() 或类似方法来强制执行 IEnumerable 或 IQueryable?

标签: c# .net async-await


【解决方案1】:

您错误地使用了async void。而是返回TaskTask<T>。考虑以下几点:

static async Task GetPurchaseOrders(string supplier)
{
    try
    {
        var purchaseOrders = await VNA.PurchaseOrders.ForSupplierAsyncTask(supplier);

        foreach (var order in purchaseOrders)
        {
            CreateXMLDocument(order, order.orderNbr, "PurchaseOrder");
        }
    }
    catch (Exception ex)
    {   // <-- Place a breakpoint here...
        // I would imagine you're getting an exception
    }
}

Task(作为返回类型)是底层异步状态机理解状态之间相关性的方式。此外,它还允许进行适当的异常处理。

您可能在数据库连接上使用IEnumerable&lt;T&gt;,并且由于它是延迟执行加上暂停异步执行,因此连接可能在尝试迭代之前或期间关闭。 try / catch 和正确使用 Task 应该有助于查明问题。

【讨论】:

  • 另外请记住,当您有异步事件处理程序时,您只想使用 async void。那是唯一合适的地方有一个 async void。
猜你喜欢
  • 2020-05-09
  • 1970-01-01
  • 2019-06-29
  • 2017-05-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 2017-01-11
  • 2019-01-15
相关资源
最近更新 更多