c# - 这是使用线程池的正确案例吗?

标签 c# winforms invoke threadpool

设置如下:我正在尝试制作一个相对简单的 Winforms 应用程序,一个使用 FeedDotNet 的提要阅读器图书馆。我的问题是关于使用线程池。由于 FeedDotNet 正在发出同步 HttpWebRequests,因此它阻塞了 GUI 线程。所以最好的办法似乎是将同步调用放在 ThreadPool 线程上,并在它工作时调用需要在窗体上更新的控件。一些粗略的代码:

private void ThreadProc(object state)
{
 Interlocked.Increment(ref updatesPending);

    // check that main form isn't closed/closing so that we don't get an ObjectDisposedException exception
 if (this.IsDisposed || !this.IsHandleCreated) return;
 if (this.InvokeRequired)
  this.Invoke((MethodInvoker)delegate
  {
   if (!marqueeProgressBar.Visible)
    this.marqueeProgressBar.Visible = true;
  });

 ThreadAction t = state as ThreadAction;
 Feed feed = FeedReader.Read(t.XmlUri);

 Interlocked.Decrement(ref updatesPending);

 if (this.IsDisposed || !this.IsHandleCreated) return;
 if (this.InvokeRequired)
  this.Invoke((MethodInvoker)delegate { ProcessFeedResult(feed, t.Action, t.Node); });

 // finished everything, hide progress bar
 if (updatesPending == 0)
 {
  if (this.IsDisposed || !this.IsHandleCreated) return;
  if (this.InvokeRequired)
   this.Invoke((MethodInvoker)delegate { this.marqueeProgressBar.Visible = false; });
 }
}

this = 主窗体实例

updatesPending = 主窗体中的 volatile int

ProcessFeedResult = 对 Feed 对象执行某些操作的方法。由于线程池线程无法返回结果,这是通过主线程处理结果的可接受方式吗?

我主要担心的是它的扩展方式。我一次尝试了约 250 个请求。我见过的最大线程数大约是 53,一旦所有线程都完成,又回到 21。我记得在我玩代码的一个特殊情况下,我看到它上升到 120。这不是'不正常,是吗?另外,在 Windows XP 上,我认为连接数如此之高,某处会出现瓶颈。我对吗?

我该怎么做才能确保线程/连接的最大效率?

所有这些问题也让我想知道这是否适合使用线程池。 MSDN 和其他来源称它应该用于“短期”任务。考虑到我的连接速度相对较快,1-2 秒是否足够“短暂”?如果用户使用 56K 拨号,并且一个请求可能需要 5-12 秒甚至更多,该怎么办?那么线程池也会是一个有效的解决方案吗?

最佳答案

ThreadPool,未选中 可能是个坏主意。

开箱即用,线程池中有 250 个线程 per cpu .

想象一下,如果您在一次突发事件中破坏了某人的网络连接,并禁止他们从某个站点接收通知,因为他们怀疑正在运行 DoS 攻击。

相反,当您从网上下载内容时,您应该建立大量的控制权。用户应该能够决定他们发出多少并发请求(以及每个域有多少并发请求),理想情况下您还希望提供对带宽量的控制。

虽然这可以通过 ThreadPool 进行编排,但拥有专用 线程或使用诸如 BackgroundWorker 类的一堆实例之类的东西是更好的选择。

关于c# - 这是使用线程池的正确案例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1748521/

相关文章:

c# - 逐个元素除法或乘法 - c# 与 f# 比较

c# - 什么数据结构适合这个?

c# - C# .WPF 中的线程调用

c# - 调用自己来绕过不同的线程? C#

java - 在没有 JConsole 的情况下使用 JMX 执行方法

c# - 努力制作算法来为益智游戏生成棋盘

C# 在 winforms 上验证文本框的输入

c# - 使用给定的 DateTime 对象获取一个月的第一天和最后一天

c# - winform中的图表显示错误点

c# - 基于64位或32位操作系统导入外部dll