【问题标题】:Proper way to Thread a foreach loop线程化foreach循环的正确方法
【发布时间】:2013-11-18 16:57:48
【问题描述】:

在过去的 30 分钟里,我一直在破解这个问题,试图线程化一个简单的 foreach 循环,无论我做什么都会抛出一些错误(第一次不使用线程框架,所以我最可能会犯一些愚蠢的语法错误)

遗憾的是我不能使用Parallel.For,因为必须保持 .net 3.5 或以下版本...有人可以告诉我正确的方法,这样我就可以回到不想尖叫的状态!!

须藤代码

void SomeMethod
{
    foreach(Touch Input in Inputlist){
        Thread thread = new Thread(new ThreadStart(this.FilterInput(Input)));
        thread.Start();
    }
}
void FilterInput(Input UnFilteredInput){
....
}

编辑:MonoDevelop 出现以下错误

  1. 表达式表示一个值,其中类型或方法组是 预计

  2. 最佳重载方法匹配 System.Threading.Thread.Thread(System.Threading.ThreadStart) 有 一些无效的参数,

  3. 参数 #1 无法将对象表达式转换为类型 System.Threading.ThreadStart

【问题讨论】:

  • 尝试在循环顶部添加Touch copy = Input; 行并将线程开始更改为Thread thread = new Thread(new ThreadStart(this.FilterInput(copy)));
  • 即使出现了同样的 3 个错误 :: (Expression denotes a value, where a type or method group was expected), (The best overloaded method match for System.Threading.Thread.Thread (System.Threading.ThreadStart) has some invalid arguments), (3: Argument #1 cannot convert object expression to type System.Threading.ThreadStart)
  • 抛开转换错误,你可能会创建太多线程,除非你在循环中放置信号量或其他东西。
  • 它是一个封闭的更新系统输入不超过 8 个滴答声,每秒不超过 50 个滴答声 所以我希望这不会成为问题
  • 好点 Andrew :: 这就是我在凌晨 1:00 编码时发生的情况 :) .... ThreadPool 是 100% 的路要走!

标签: c# multithreading for-loop foreach c#-3.0


【解决方案1】:

首先,对于这样的事情,您应该使用重量更轻的线程池而不是完整的线程。 (而且你也确实犯了一些铸造错误,线程池版本使用与 Thread 相同的样式,因此您可以看到差异)

void SomeMethod
{
    foreach(Touch input in Inputlist){
        ThreadPool.QueueUserWorkItem(new WaitCallback(FilterInput), input);
    }
}
void FilterInput(object unCastUnFilteredInput){
    Touch UnFilteredInput = (Touch)unCastUnFilteredInput;
....
}

但是我仍然会担心每秒创建太多线程,并且会推荐某种阻塞来衡量可以创建新线程的速率。

const int MaxConcurrentThreads = 4;

private readonly Semaphore _inputLimiter = new Semaphore(MaxConcurrentThreads,MaxConcurrentThreads);

void SomeMethod
{
    foreach(Touch input in Inputlist){
        _inputLimiter.WaitOne();
        ThreadPool.QueueUserWorkItem(new WaitCallback(FilterInput), input);
    }
}
void FilterInput(object unCastUnFilteredInput){
    try
    {
        Touch UnFilteredInput = (Touch)unCastUnFilteredInput;
        ....
    {
    finally
    {
        //use a try-finally so the semaphore still gets released in the event a exception happens in the .... region.
        _inputLimiter.Release();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 2016-10-10
    • 2022-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多