首页 >后端开发 >C++ >如何限制.NET中的并发异步I/O操作?

如何限制.NET中的并发异步I/O操作?

Barbara Streisand
Barbara Streisand原创
2025-02-01 20:46:14666浏览

How to Limit Concurrent Async I/O Operations in .NET?

在 .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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn