我正在制作一个应用程序,显示一些从Windows表单中从Web收集的数据,今天我必须依次等待下载所有数据,然后再显示它们,我如何并行执行此操作在有限的队列(具有最大并发任务执行)中,在下载时显示结果刷新数据?
我今天拥有的是一种方法
internal async Task<string> RequestDataAsync(string uri)
{
var wb = new System.Net.WebClient(); //
var sourceAsync = wb.DownloadStringTaskAsync(uri);
string data = await sourceAsync;
return data;
}
我放在foreach()结束后,将数据解析为自定义对象列表,然后将该对象转换为数据表并将dataGridView绑定到该列表。
我不确定最好的方法是否是在https://msdn.microsoft.com/library/system.threading.tasks.tasks.taskscheduler.aspx上使用Limited ConcurrencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLencyLevelTaskScheduler.aspx资源被倾斜),或者有最好的方法。
我不喜欢同时启动所有任务,因为有时可能是我必须同时请求100个倾斜,我喜欢它将被执行,例如,最多可同时执行10个任务。
我知道这是一个涉及控制并发任务并在下载时报告的问题,但不确定如今什么是最好的。
我通常不推荐我的书,但我认为这会帮助您。
并发异步通过Task.WhenAll
(我的书中的食谱2.4):
List<string> uris = ...;
var tasks = uris.Select(uri => RequestDataAsync(uri));
string[] results = await Task.WhenAll(tasks);
要限制并发性,请使用SemaphoreSlim
(我的书中的食谱11.5):
List<string> uris = ...;
var semaphore = new SemaphoreSlim(10);
var tasks = uris.Select(async uri =>
{
await semaphore.WaitAsync();
try { await RequestDataAsync(uri); }
finally { semaphore.Release(); }
});
string[] results = await Task.WhenAll(tasks);
要处理数据到达时,请引入另一种async
方法(我的书中的配方2.6):
List<string> uris = ...;
var semaphore = new SemaphoreSlim(10);
var tasks = uris.Select(async uri =>
{
await semaphore.WaitAsync();
try { await RequestAndProcessDataAsync(uri); }
finally { semaphore.Release(); }
});
await Task.WhenAll(tasks);
async Task RequestAndProcessDataAsync(string uri)
{
var data = await RequestDataAsync(uri);
var myObject = Parse(data);
_listBoundToDataTable.Add(myObject);
}