在 .NET 中限制並發異步 I/O 操作
異步編程為並行任務提供了顯著優勢。但是,管理這些異步操作的並發性對於避免系統超負荷至關重要。本文討論了限制並發異步 I/O 操作數量的常見問題,以確保最佳性能。
問題:
在需要使用異步 HTTP 請求並發獲取多個 URL 的情況下,默認行為是創建大量同時請求。這可能導致資源耗盡和性能下降。挑戰在於將並發性限制在指定的閾值,例如一次 20 個請求。
解決方案:
.NET 4.5 Beta 引入了異步信號量 (SemaphoreSlim),提供了一種有效的方法來控制對資源的並發訪問。 WaitAsync() 方法允許我們在指定數量的槽可用之前暫停異步方法的執行。
示例代碼:
<code class="language-csharp">public async Task MyOuterMethod() { // 要获取的 URL 列表 string[] urls = { "http://google.com", "http://yahoo.com", ... }; // 创建一个节流器,将并发性限制为 20 个请求 SemaphoreSlim throttler = new SemaphoreSlim(initialCount: 20); // 初始化一个列表以存储所有异步任务 var allTasks = new List<Task>(); // 安排每个 URL 获取任务 foreach (var url in urls) { // 等待节流器中的一个槽可用 await throttler.WaitAsync(); // 在单独的线程池流中安排任务 allTasks.Add( Task.Run(async () => { try { using (var client = new HttpClient()) // 使用using语句确保HttpClient被正确释放 { var html = await client.GetStringAsync(url); } } finally { // 释放节流器中的槽 throttler.Release(); } })); } // 等待所有任务完成 await Task.WhenAll(allTasks); }</code>
在此代碼中,WaitAsync() 方法確保一次只執行 20 個請求。當安排新的請求時,它會在繼續之前等待直到有槽可用。
使用任務調度的替代解決方案:
另一種方法涉及使用基於 TPL 的調度創建委託綁定任務。然後可以實現自定義任務調度器來強制執行並發限制。有關更多信息,請參閱 MSDN 上關於 TaskScheduler 的示例。
以上是如何限制.NET中的並發異步I/O操作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!