是什么区别Task.WaitAll(),并Task.WhenAll()从异步CTP?您能提供一些示例代码来说明不同的用例吗?
我想并行处理一个集合,但是我在实现它时遇到了麻烦,因此我希望得到一些帮助.
如果我想在并行循环的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.
我有一个Windows服务,根据计划运行各种作业.确定要运行的作业后,会将一个计划对象列表发送到迭代列表并运行每个作业的方法.问题是由于外部数据库调用,某些作业最多可能需要10分钟才能运行.
我的目标是没有一个工作阻止其他队列,基本上一次有多个运行.我认为使用async和await可以解决这个问题,但我以前从未使用过这些.
现行代码:
public static bool Load(List<Schedule> scheduleList)
{
foreach (Schedule schedule in scheduleList)
{
Load(schedule.ScheduleId);
}
return true;
}
public static bool Load(int scheduleId)
{
// make database and other external resource calls
// some jobs run for up to 10 minutes
return true;
}
Run Code Online (Sandbox Code Playgroud)
我尝试更新到这段代码:
public async static Task<bool> LoadAsync(List<Schedule> scheduleList)
{
foreach (Schedule schedule in scheduleList)
{
bool result = await LoadAsync((int)schedule.JobId, schedule.ScheduleId);
}
return true;
}
public async static Task<bool> LoadAsync(int scheduleId)
{
// make database …Run Code Online (Sandbox Code Playgroud) 我一直在努力学习C#与HttpClient的异步,并遇到了一个我无法弄清楚发生了什么的问题.
我想做的事:
问题:
每当我一起发送请求列表时,响应似乎要花费更长的时间,但它们应该大致相同.例如:
所用时间:67.9609毫秒所用
时间:89.2413毫秒所用
时间:100.2345毫秒所用
时间:117.7308毫秒所用
时间:127.6843毫秒所用
时间:132.3066毫秒所用
时间:157.3057毫秒
什么时候它们都应该只有70毫米左右...这对于每一批新产品都会重复; 第一个是快速的,然后每个连续的减速.
我的代码
有3个主要部分.我已经简化了它,我可以专注于问题发生的地方(Downloader.cs是我的时间)
Downloader.cs这包含执行实际http查询的方法:
public async Task<string> DownloadData(string requestString)
{
HttpResponseMessage response;
response = await this.httpClient.PostAsync( url, new StringContent( requestString ));
string returnString = await response.Content.ReadAsStringAsync();
return returnString;
}
Run Code Online (Sandbox Code Playgroud)QueryAgent.cs这初始化一个新的Downloader并包含主异步循环调用函数和它在循环中调用的异步方法.
我需要尽快发送新的请求,具体取决于最后一组响应的结果(基本上,请求发出的速率可能会发生变化,所以我不能在结束时执行Task.delay() while循环)
public async Task DownloadLoopAsync()
{
while ( this.isLooping )
{
// I put this here to stop it using lots of cpu.
// Not sure if it is best …Run Code Online (Sandbox Code Playgroud)我目前正在优化现有的,非常慢的和超时的生产应用程序。没有选择来重写它。
简而言之,这是一个WCF服务,当前依次调用其他四个“工作者” WCF服务。任何一个工人服务都不依赖于另一个的结果。因此,我们希望一次全部调用它们(而不是顺序调用)。我要重申的是,我们没有重写的奢望。
优化涉及使其立即调用所有工作者服务。这是想到异步的地方。
我在异步编程方面的经验有限,但是对于我的解决方案,我已经就该主题进行了尽可能多的阅读。
问题是,在测试中,它可以工作,但使我的CPU耗尽。谢谢您的帮助
以下是主要WCF服务中基本代码的简化版本
// The service operation belonging to main WCF Service
public void ProcessAllPendingWork()
{
var workerTasks = new List<Task<bool>>();
foreach(var workerService in _workerServices)
{
//DoWorkAsync is the worker method with the following signature:
// Task<bool> DoWorkAsync()
var workerTask = workerService.DoWorkAsync()
workerTasks.Add(workerTask);
}
var task = Task.Run(async ()=>
{
await RunWorkerTasks(workerTasks);
});
task.Wait();
}
private async RunWorkerTasks(IEnumerable<Tast<bool>> workerTasks)
{
using(var semaphore = new SemaphoreSlim(initialCount:3))
{
foreach (var workerTask in workerTasks)
{ …Run Code Online (Sandbox Code Playgroud) 我有一种情况,我希望异步启动用户定义的任务数,并等待所有任务完成.简化,这是我正在处理的:
[TestMethod]
public async Task Start() {
var numDrivers = 2;
while (numDrivers != 0) {
var rnd = new Random();
var r = rnd.Next(itemArray.Count);
var target = itemArray[r];
var proxyDriver = GetProxiedDriver();
Task.Run(() => HandleIntro(proxyDriver, target));
numDrivers--;
}
}
Run Code Online (Sandbox Code Playgroud)
对于某些上下文 - 这些是Selenium webdrivers开始运行一些UI测试.我看到浏览器弹出,但是一旦Task.Run()完成,所有执行都会停止.n在停止执行之前,如何在等待所有驱动程序完成之前触发驱动程序以异步方式运行?
我已经尝试了await Task.Run(() => HandleIntro(proxyDriver, target));但这等待任务,他们不会同时运行.
HandleIntro:
private async Task HandleIntro(FirefoxDriver driver, string target) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud) 我有点困惑,我应该如何实现多个异步任务的worklflow.例如 - Task1启动,当Task1完成,Task2启动,Task2完成启动TaskN等.
或者另一个词 - 异步任务如何通知"父"任务有关他的状态?我想可以在这里使用TaskStatus但不确定究竟如何.我在MSDN上搜索过,但没有这种模式的完整示例.
PS我编辑我的问题,以便专注于一个特定的问题.
我有一个应用程序,我需要做两个I/O任务:获取GPS位置,通过蓝牙检索一些数据.这两项任务都可以在不同时间内完成,并且可能需要很长时间.为了提高应用程序的速度,我想同时启动两个活动,然后等待两个活动完成再继续.
如果我这样做:
bool locationStatus= await GetCurrentLocation();
bool vehicleStatus = await GetVehicleData();
Run Code Online (Sandbox Code Playgroud)
第二个功能是否被启动,或者只是未被阻止的UI?
我需要调用并行任务吗?