相关疑难解决方法(0)

在Parallel.ForEach中嵌套等待

在metro应用程序中,我需要执行许多WCF调用.有大量的调用,所以我需要在并行循环中进行调用.问题是并行循环在WCF调用完成之前退出.

你会如何重构这个按预期工作?

var ids = new List<string>() { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
var customers = new  System.Collections.Concurrent.BlockingCollection<Customer>();

Parallel.ForEach(ids, async i =>
{
    ICustomerRepo repo = new CustomerRepo();
    var cust = await repo.GetCustomer(i);
    customers.Add(cust);
});

foreach ( var customer in customers )
{
    Console.WriteLine(customer.ID);
}

Console.ReadKey();
Run Code Online (Sandbox Code Playgroud)

c# wcf task-parallel-library async-await parallel.foreach

159
推荐指数
9
解决办法
10万
查看次数

与异步lambda并行的foreach

我想并行处理一个集合,但是我在实现它时遇到了麻烦,因此我希望得到一些帮助.

如果我想在并行循环的lambda中调用C#中标记为async的方法,则会出现问题.例如:

var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
  // some pre stuff
  var response = await GetData(item);
  bag.Add(response);
  // some post stuff
}
var count = bag.Count;
Run Code Online (Sandbox Code Playgroud)

计数为0时会出现问题,因为创建的所有线程实际上只是后台线程,并且Parallel.ForEach调用不等待完成.如果我删除async关键字,该方法如下所示:

var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, item =>
{
  // some pre stuff
  var responseTask = await GetData(item);
  responseTask.Wait();
  var response = responseTask.Result;
  bag.Add(response);
  // some post stuff
}
var count = bag.Count;
Run Code Online (Sandbox Code Playgroud)

它工作,但它完全禁用等待聪明,我必须做一些手动异常处理..(为简洁起见删除).

如何实现一个Parallel.ForEach在lambda中使用await关键字的循环?可能吗?

Parallel.ForEach方法的原型采用Action<T>as参数,但我希望它等待我的异步lambda.

c# task-parallel-library async-await parallel.foreach

100
推荐指数
6
解决办法
7万
查看次数

在Action中使用ForEachAsync并等待时不等待

以下应返回"C",但返回"B"

using System.Data.Entity;
//...
var state = "A";
var qry = (from f in db.myTable select f);
await qry.ForEachAsync(async (myRecord) => {
   await DoStuffAsync(myRecord);
   state = "B";
});
state = "C";
return state;
Run Code Online (Sandbox Code Playgroud)

它不等待DoStuffAsync完成,state="C"运行然后state="B"执行(因为它内部仍在等待).

.net c# asynchronous entity-framework async-await

4
推荐指数
1
解决办法
7602
查看次数

ForEach() 方法中的异步 lambda 是如何处理的?

我们在我们的产品中遇到了一个错误,并将其简化为以下问题。给定一个列表并使用异步 lambda 调用 ForEach-Extension 方法,输出的预期顺序是什么:

public static async Task Main()
{
    var strings = new List<string> { "B", "C", "D" };
    Console.WriteLine("A");
    strings.ForEach(async s => { await AsyncMethod(s); } );
    Console.WriteLine("E");
}

private static async Task AsyncMethod(string s)
{
    await Task.Run(() => { Console.WriteLine(s); });
}
Run Code Online (Sandbox Code Playgroud)

我们期望它总是 A、B、C、D、E。但有时是 A,B,C,E,D 或 A,B,E,D,C

我们认为这两行是等价的:

strings.ForEach(async s => { await AsyncMethod(s); });

foreach (var s in strings) await AsyncMethod(s);
Run Code Online (Sandbox Code Playgroud)

有人能解释一下区别在哪里吗?这些异步 lambda 是如何执行的,为什么不等待它们?

澄清:问题不是B,C,D的顺序。问题是E在循环完成之前出现

c# linq async-await

4
推荐指数
2
解决办法
5110
查看次数

不等待lambda foreach中的异步调用

我有以下方法在完成之前返回(方法为简洁而减少):

private void ProcessAllItems(List<Item> items)
{
    items.ForEach(async item =>
    {
        var response = await Processor.IOBoundTaskAsync(item);
        // Some further processing on the response object.
    });
}
Run Code Online (Sandbox Code Playgroud)

Processor.IOBoundTaskAsync方法返回Task <SomeResponseObject>,因此不是void.

那么,发生了什么?

我希望lambda foreach一次处理一个项目,所以不能并行处理.对于第一次迭代,代码进入IOBoundTaskAsync并获取第一个"await"(它调用4个等待的Web服务方法中的第一个),然后调用方法"ProcessAllItems"退出.

我只使用测试数据,因此我的列表中只有1个项目.

我错过了什么?

c# lambda asynchronous task-parallel-library async-await

3
推荐指数
1
解决办法
896
查看次数

foreach与Task.WhenAll()-执行上有什么区别吗?

在我的应用程序中的管道上,有一个选项可以注入一组预请求处理程序,这些请求处理程序可以在请求首次进入管道时对其进行更改。管道是完全异步的,因此必须等待这些请求前处理程序调用(以及其他所有请求)。我有几种不同的方式来调用这些处理程序,我想知道它们之间是否有任何区别,如果有什么区别?例如,是否将各种处理程序以相同的顺序调用?哪个选项可能提供最佳性能?

选项1:foreach

foreach (var handler in this.preRequestHandlers)
{
    await handler.Handle(request);
}
Run Code Online (Sandbox Code Playgroud)

选项2:ForEach()

this.preRequestHandlers.ForEach(async handler => await handler.Handle(request));
Run Code Online (Sandbox Code Playgroud)

选项3:Task.WhenAll()

await Task.WhenAll(this.preRequestHandlers.Select(handler => handler.Handle(request)));
Run Code Online (Sandbox Code Playgroud)

c# asynchronous async-await

1
推荐指数
2
解决办法
1388
查看次数

在 Linq 表达式中使用 Async/Await 不会引发异常

晚上,

谁能指出我为什么使用 async 和 await 运算符的 linq 语句不会在堆栈上传播异常但 foreach 循环会传播的文档?必须有一些隐藏的东西并在某处记录了这种行为,我只是没有运气找到它。#googlefoofail #doyouevenasyncbrah

如果您运行单元测试,您将看到它返回时没有错误且有效。但是,如果您调试单元测试,它会因错误而中断,但是它将允许您继续,并且该错误永远不会传播回堆栈。

如果您注释掉 linq 语句并取消注释 foreach 循环,那么在尝试向字典添加重复键时会出现预期的错误。

[TestMethod]
public void tester()
{
    List<KeyValuePair<string, string>> pairs = new List<KeyValuePair<string, string>>() 
    { 
        { new KeyValuePair<string, string>("test", "first") }, 
        { new KeyValuePair<string, string>("test", "second") } 
    };
    fails = new Dictionary<string, string>();

    pairs.ForEach(async x => await testasync(x));                //<========= does not throw error

    //foreach (KeyValuePair<string,string> pair in pairs)        //<========= throws error
    //{
    //    testasync(pair).GetAwaiter().GetResult();
    //}

    Assert.IsTrue(1 == 1);
}

private Dictionary<string, string> fails;
private async …
Run Code Online (Sandbox Code Playgroud)

c# linq exception async-await

1
推荐指数
1
解决办法
67
查看次数