gpt4 book ai didi

c# - 用于错误处理的并行 I/O 和重试逻辑

转载 作者:行者123 更新时间:2023-12-03 08:00:23 25 4
gpt4 key购买 nike

通常并行处理仅与 CPU 密集型操作相关。但是,PLINQ 使用 WithDegreeOfParallelism 扩展专门提供 IO 密集型支持。例如:

from site in new[]
{
"www.albahari.com",
"www.linqpad.net",
"www.oreilly.com",
"www.takeonit.com",
"stackoverflow.com",
"www.rebeccarey.com"
}
.AsParallel().WithDegreeOfParallelism(6)
let p = new Ping().Send (site)
select new
{
site,
Result = p.Status,
Time = p.RoundtripTime
}

但是如果 supporting IO is the goal of WithDegreeOfParallelism ,那么如何进一步扩展或使用 PLINQ 来实现“重试”效果,这是典型的 IO 操作?那么“延迟”效应呢?

例如,如果通过 WCF 服务调用的 IO 引发 CommunicationException,我可能希望在继续下一个资源之前使用“3 次尝试”策略再次发出相同的请求。我可能还想在每次尝试之间等待一分钟。虽然我在每次尝试之间“等待”一分钟,但我不希望线程阻塞等待。

在这个 MSDN article作者从一个类似于我上面显示的查询开始。然后他转换查询,以便没有线程阻塞。不幸的是,他在此过程中失去了 WithDegreeOfParallelism。无论哪种方式,他都没有解决发生错误时的“重试”问题。

任何人都知道或知道这样做的巧妙方法吗?

我正在考虑制作一个特殊的 IEnumerable 包装器,允许在 PLINQ 遍历集合时“重新插入”值。这确实会导致“重试”行为,但仍然不允许“重试之间的 1 分钟延迟”要求。我可以使用 Thread.Sleep() 创建 1 分钟的延迟,但我尽量不阻塞线程。

想法?

最佳答案

你的文章linked实际上展示了如何通过使用 Task 来避免阻塞 IO 绑定(bind)操作的线程。 - 基于 API ( DownloadDataTask ) 代替:

However, there’s still something about this code that is not ideal. The work (sending off download requests and blocking) requires almost no CPU, but it is being done by ThreadPool threads since I’m using the default scheduler. Ideally, threads should only be used for CPU-bound work (when there’s actually work to do).



使用 PLINK/ Task.Run/ Task.Factory.StartNew对于基于 IO 的操作是 反模式 . PLINQ(与 Parallel.For 等相同)适用于 CPU 密集型计算工作,但为自然异步网络/IO 密集型操作分配和阻塞线程是没有意义的,它根本不需要线程,而“飞行中”。按照您显示的示例代码,这将类似于 new Ping().SendAsync(site) ,返回 Task .然后你可以做 await Task.WhenAll(tasks)并处理错误。

引用 "There Is No Thread"作者:Stephen Cleary,以及他最近的 answer解决并行 IO 的最大程度。最重要的是,很容易合并重试逻辑,而无需涉及任何线程(例如,像 this )。

关于c# - 用于错误处理的并行 I/O 和重试逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22238930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com