在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) 我已经尝试了一段时间来获得一些我认为可以简单地使用.NET 4.5的东西
我想同时启动两个长时间运行的任务,并
以最佳的C#4.5(RTM)方式收集结果
以下作品,但我不喜欢它,因为:
Sleep成为一个异步方法,所以它可以是await其他方法Task.Run()工作代码:
public static void Go()
{
Console.WriteLine("Starting");
var task1 = Task.Run(() => Sleep(5000));
var task2 = Task.Run(() => Sleep(3000));
int totalSlept = task1.Result + task2.Result;
Console.WriteLine("Slept for a total of " + totalSlept + " ms");
}
private static int Sleep(int ms)
{
Console.WriteLine("Sleeping for " + ms);
Thread.Sleep(ms);
Console.WriteLine("Sleeping for " + ms + " FINISHED");
return ms;
}
Run Code Online (Sandbox Code Playgroud)
非工作代码:
更新:这实际上是有效的,并且是正确的方法,唯一的问题是 Thread.Sleep
此代码不起作用,因为调用Sleep(5000)立即启动任务运行,因此Sleep(1000) …
我想并行处理一个集合,但是我在实现它时遇到了麻烦,因此我希望得到一些帮助.
如果我想在并行循环的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.
我有这样的方法:
public async Task<MyResult> GetResult()
{
MyResult result = new MyResult();
foreach(var method in Methods)
{
string json = await Process(method);
result.Prop1 = PopulateProp1(json);
result.Prop2 = PopulateProp2(json);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
然后我决定使用Parallel.ForEach:
public async Task<MyResult> GetResult()
{
MyResult result = new MyResult();
Parallel.ForEach(Methods, async method =>
{
string json = await Process(method);
result.Prop1 = PopulateProp1(json);
result.Prop2 = PopulateProp2(json);
});
return result;
}
Run Code Online (Sandbox Code Playgroud)
但现在我有一个错误:
在异步操作仍处于挂起状态时完成异步模块或处理程序.
我试图了解Async和Await是如何工作的.如何控制程序中的旅行.这是我试图理解的代码.
public async Task MyMethod()
{
Task<int> longRunningTask = LongRunningOperation();
//indeed you can do independent to the int result work here
MySynchronousMethod();
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
await Task.Delay(5000); //5 seconds delay
return 1;
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
MyMethod();
}
Run Code Online (Sandbox Code Playgroud)
当按钮点击发生时,MyMethod()将被调用,并且将调用MyMethod LongRunningOperation(),并且需要5秒才能完成.所以我的问题是
这条线的意义是什么?
任务longRunningTask …