我如何从Internet下载资源,并在C#(Winforms)中立即报告(同时使用最大并发任务)



我正在制作一个应用程序,显示一些从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);
}

最新更新