我如何从互联网上下载资源并在 c# (winforms) 中立即报告(同时处理最大并发任务)
How I can download resources from internet and report that immediately (with max concurrent tasks at same time) in c# (winforms)
我正在制作一个应用程序,以 windows 形式显示从网络收集的一些数据,今天我必须等待顺序下载所有数据才能显示它们,如何在有限队列(执行最大并发任务)以显示下载时刷新数据网格视图的结果?
我今天有一个方法
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() 上,在它结束后,将数据解析为自定义对象列表,然后将该对象转换为 DataTable 并将 datagridview 绑定到它。
我不确定最好的方法是使用 https://msdn.microsoft.com/library/system.threading.tasks.taskscheduler.aspx 上的示例中的 LimitedConcurrencyLevelTaskScheduler(我不确定每次下载资源时如何向网格报告)或者是否有最好的方法来执行此操作。
我不喜欢同时启动所有任务,因为有时我必须同时请求 100 个下载,我喜欢它最多同时执行 10 个任务。
我知道这是一个涉及控制并发任务并在下载时报告的问题,但不确定现在最好的做法是什么。
我不经常推荐my book,但我认为它会对你有所帮助。
并发异步是通过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);
}
我正在制作一个应用程序,以 windows 形式显示从网络收集的一些数据,今天我必须等待顺序下载所有数据才能显示它们,如何在有限队列(执行最大并发任务)以显示下载时刷新数据网格视图的结果?
我今天有一个方法
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() 上,在它结束后,将数据解析为自定义对象列表,然后将该对象转换为 DataTable 并将 datagridview 绑定到它。
我不确定最好的方法是使用 https://msdn.microsoft.com/library/system.threading.tasks.taskscheduler.aspx 上的示例中的 LimitedConcurrencyLevelTaskScheduler(我不确定每次下载资源时如何向网格报告)或者是否有最好的方法来执行此操作。
我不喜欢同时启动所有任务,因为有时我必须同时请求 100 个下载,我喜欢它最多同时执行 10 个任务。
我知道这是一个涉及控制并发任务并在下载时报告的问题,但不确定现在最好的做法是什么。
我不经常推荐my book,但我认为它会对你有所帮助。
并发异步是通过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);
}