Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这是使用线程池的正确案例吗?_C#_Winforms_Invoke_Threadpool - Fatal编程技术网

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

C# 这是使用线程池的正确案例吗?,c#,winforms,invoke,threadpool,C#,Winforms,Invoke,Threadpool,设置如下:我正在尝试制作一个相对简单的Winforms应用程序,一个使用库的提要阅读器。我的问题是关于使用线程池。由于FeedDotNet正在生成同步HttpWebRequests,它正在阻塞GUI线程。因此,最好的方法似乎是将同步调用放在线程池线程上,并在其工作时调用表单上需要更新的控件。一些粗略的代码: private void ThreadProc(object state) { Interlocked.Increment(ref updatesPending); // che

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

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; });
 }
}
=主窗体实例

updateSpend
=主窗体中的volatile int

ProcessFeedResult
=对提要对象执行某些操作的方法。由于线程池线程不能返回结果,这是通过主线程处理结果的一种可接受的方法吗

我最担心的是它的规模。我一次尝试了250个请求。我看到的最大线程数大约是53个,一旦所有线程都完成了,返回到21个。我记得有一次我玩代码的时候,看到代码高达120。这不正常,是吗?另外,在WindowsXP上,我认为有这么多的连接,在某个地方会有一个瓶颈。我说得对吗

如何确保线程/连接的最大效率


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

您可能想看看这个课程。

我对线程池的理解是,它是为这种情况而设计的。我认为短命的定义是这样的时间顺序——甚至可能长达几分钟。“长寿命”线程应该是在应用程序的生命周期内处于活动状态的线程


别忘了,微软会花一些时间尽可能提高线程池的效率。你认为你能写些更有效率的东西吗?我知道我做不到。

线程池,未选中可能是个坏主意

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

想象一下,如果在一次突发事件中,你让某人的网络连接变得平坦,并禁止他们从站点获取通知,因为他们被怀疑正在运行DoS攻击

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


虽然这可以通过线程池进行协调,拥有专用的线程或使用BackgroundWorker类的一些实例是一个更好的选择。

NET线程池是专门为执行短时间运行的任务而设计的,创建新线程的开销会抵消创建新线程的好处。它不是为长时间阻塞或执行时间长的任务而设计的

这个想法是为了让一个任务跳到一个线程上,快速运行,完成并跳下

该类提供了一种在线程池线程上执行任务的简单方法,并提供了任务报告进度和处理取消请求的机制

在BackgroundWorker组件中,文件下载被明确给出,作为适当使用此类的示例。这应该会鼓励你使用这个类来完成你需要的工作

如果您担心过度使用线程池,您可以确信运行时会根据需要管理可用线程的数量。任务在线程池中排队等待执行。当一个线程可以执行工作时,任务被加载到该线程上。监视进程定期检查线程池的状态。如果有任务等待执行,它可以创建更多线程。如果有几个空闲线程,它可以关闭一些线程以释放资源


在更糟糕的情况下,如果所有线程都很忙,并且您的工作已排队,则运行时将添加线程以处理额外的工作负载。应用程序将运行得更慢,因为它必须等待更多线程可用,但它将继续运行。

几点,并结合信息形成其他一些答案:

  • ThreadProc不包含异常处理。您应该添加该选项,否则1个I/O错误将停止进程
  • Sam Saffron说得很对,你应该限制线程的数量。您可以使用(线程安全)队列将提要推入(工作项),并让1+个线程在循环中读取队列中的内容
  • BackgroundWorker可能是个好主意,它将为您提供所需的异常处理和同步
  • 后台工作人员使用线程池,这很好

请原谅我不停的唠叨,我还是个新手。不,我不认为我可以:)我担心的是Windows最多只能连接10个连接(我想每个应用最多只能连接10个)。其他30个线程是否在等待一个空闲连接,而实际上只有10个线程在做真正的工作?这就是我想知道的。你说得很好,谢谢。我倾向于幕后工作者。有多少实例是“太多”?我知道这一切都取决于用户的连接,但任何超过某个数字(比如,25?)都会造成相同的问题,是吗?在应用程序中有多个默认值,每种连接类型一个,让用户选择她的互联网速度。我会选择3个线程,每个域的低端限制为一个,而高端限制为10个。25