以有限并发数并行执行

2024-03-03

我想在 Silverlight 5 中以有限的并发性并行执行异步操作。

我的代码是这样的:

    public async void btn_click(object s, RoutedEventArgs e)
    {
        await DoAllWork();
    }

    private async Task DoAllWork()
    {
        //Get work to do
        int[] wrk = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        //Start the tasks
        Task[] tasks = new Task[wrk.Length];
        for (int i = 0; i < wrk.Length; i++)
        {
            int item = wrk[i];
            tasks[i] = WorkSingleItem(item);
        }
        await TaskEx.WhenAll(tasks);
    }

    private async Task WorkSingleItem(int item)
    {
        //a very long operation
        var response = await Request(item);
        await Handle(response);
    }

我找到了这篇文章:http://msdn.microsoft.com/en-us/library/ee789351(v=vs.110).aspx http://msdn.microsoft.com/en-us/library/ee789351(v=vs.110).aspx

我如何等待我的工作方法,该方法使用“有限并发调度程序”启动所有长时间操作,并且每个项目工作不依赖同步上下文以避免在 UI 线程中执行代码...


由于您的长操作异步处理 I/O,并且限制并发的目的是避免 DDoS,那么TaskScheduler是一个不正确的解决方案。这是因为一个TaskScheduler仅控制活动任务(运行或阻塞);当任务通过以下方式返回到其调度程序时await,它不再被视为“活跃”。所以,一个TaskScheduler如果您的 I/O 是异步的,则不能用于防止 DDoS。

正确的解决方案是使用类似async-兼容信号量 http://blogs.msdn.com/b/pfxteam/archive/2012/02/12/10266983.aspx:

public async void btn_click(object s, RoutedEventArgs e)
{
  await Task.Run(() => DoAllWork());
}

private async Task DoAllWork()
{
  int[] wrk = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  var semaphore = new AsyncSemaphore(4);

  var tasks = wrk.Select(x => WorkSingleItem(x, semaphore));

  await TaskEx.WhenAll(tasks);
}

private async Task WorkSingleItem(int item, AsyncSemaphore semaphore)
{
  await semaphore.WaitAsync();
  try
  {
    var response = await Request(item);
    await Handle(response);
  }
  finally
  {
    semaphore.Release();
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以有限并发数并行执行 的相关文章

随机推荐