2011-12-22 40 views
0

我期待到使用新的异步/ C#中5等待图片关键词和阅读this article使用时控制线程数量C#5异步/伺机

我看到下面的例子

async void ArchiveDocuments(List<Url> urls) 
{ 
    Task archive = null; 
    for(int i = 0; i < urls.Count; ++i) 
    { 
    var document = await FetchAsync(urls[i]); 
    if (archive != null) 
     await archive; 
    archive = ArchiveAsync(document); 
    } 
} 

据推测,如果网址列表非常长,我们可能会陷入线程崩溃失控的情况。

我想知道的是推荐的方法来控制使用的线程数。有没有办法指定一个线程池或最大数量?

使用TPL,您可以使用选项来控制最大线程数 ParallelOptions.MaxDegreeOfParallelism。也许某种组合等待和任务的方式可能是可能的。

回答

1

该示例的要点是显示一个“管道”模式,其中最多只有一个提取和一个存档同时执行。

async并不意味着并发,它意味着非阻塞。

+0

感谢您的回复,但我只是使用snippit作为在循环中使用await的示例。我试图找到它将使用多少线程的底部。如果await在这样的循环中,那么循环仅在await返回后继续。 从那篇文章: “如果我们正在等待的任务尚未完成,则将该方法的其余部分注册为该任务的继续,然后立即返回给调用者; “ 这似乎表明,只有一个线程将用于FetchAsync – 2011-12-22 12:09:50

+0

当您执行'await'表达式时,'async'方法的其余部分,包括任何类似状态循环索引,存储在状态机对象中。然后'async'方法返回控制给它的调用者 - 它退出。所以不,循环不会继续执行。当等待的方法完成时,控制权返回到状态机,然后状态机继续执行。 – 2011-12-22 12:18:50

+0

这里有一些*并发性,如果你以另一种方式来看待它。当'async'方法由于'await'返回给它的调用者时,'async'方法本身不会继续运行,但'Fetch'和/或'Archive'操作*做*。我将'async' /'await'视为一种以编程友好的方式管理并发的方式。 – 2011-12-22 17:31:10

0

asyncawait关键字本身不会创建任何线程。这完全取决于处理任务本身的方法。实际上,文件系统I/O或网络连接等操作通常不需要任何线程异步运行。硬件完成硬件的功能,完成后会触发相关事件(回到C#中)。

如果要控制线程数,则需要更改创建线程的方法 - 而且它与asyncawaits无关。