.net 多参数化线程效率

.net 多参数化线程效率,.net,multithreading,parameters,.net,Multithreading,Parameters,有没有更优雅的方法来编写以下语法 Thread t0 = new Thread(new ParameterizedThreadStart(doWork)); t0.Start('someVal'); t0.Join(); Thread t1 = new Thread(new ParameterizedThreadStart(doWork)); t1.Start('someDiffVal'); t1.

有没有更优雅的方法来编写以下语法

        Thread t0 = new Thread(new ParameterizedThreadStart(doWork));
        t0.Start('someVal');
        t0.Join();

        Thread t1 = new Thread(new ParameterizedThreadStart(doWork));
        t1.Start('someDiffVal');
        t1.Join();
假设我们想要传递20个不同的值,那么设置它的最佳方法是什么?循环通过并在末端连接

如果没有实例化一个新线程(如下所示),那么该线程将无法重新启动。例如:

        Thread t1 = new Thread(new ParameterizedThreadStart(doWork));
        t1.Start('someVal');
        t1.Start('someDiffVal');

为什么你要开始一个线程,然后立即加入它

我通常会这样做:

List<Thread> threads = new List<Thread>();

foreach (string item in items)
{
    string copy = item; // Important due to variable capture
    ThreadStart ts = () => DoWork(copy); // Strongly typed :)
    Thread t = new Thread(ts);
    t.Start();
    threads.Add(t);
}

foreach (Thread t in threads)
{
    t.Join();
}
List threads=newlist();
foreach(项中的字符串项)
{
string copy=item;//由于变量捕获而很重要
ThreadStart ts=()=>DoWork(复制);//强类型:)
螺纹t=新螺纹(ts);
t、 Start();
添加(t);
}
foreach(螺纹中的螺纹t)
{
t、 Join();
}
另一个选项(在.NET 4.0中或与CTP一起)是
Parallel.ForEach的一种形式。不过,这并不一定可行。我还看到一篇很好的博客文章(不记得是谁写的)在这里使用了
IDisposable
,即

using(StartThread(arg1))
using(StartThread(arg2))
{
}

Dispose()方法在生成的线程上进行了连接,即退出块时,所有操作都已完成。非常可爱。

为什么不让参数成为类的一部分,使其成为属性,并让get/set方法锁定它们?如果有足够的参数,请使参数对象本身成为对象的属性,然后锁定该参数块。例如:

class GonnaDoSomeThreading {
   private Object mBlockLock = new Object();
   private MyParameterBlock mBlock;
   public MyParameterBlock Block {
       get { 
            MyParameterBlock tmp;
            lock (mBlockLock){
                tmp = new MyParameterBlock(mBlock); //or some other cloning
            }
            return tmp; //use a tmp in order to make sure that modifications done
                        //do not modify the block directly, but that modifications must
                        //be 'committed' through the set function
       }
       set { lock (mBlockLock){ mBlock = value; } } 
   }
}
然后按照已经建议的方式创建线程池。这样,数据访问周围就有了锁,这样,如果所有线程都需要它,它们就可以互相等待

如果您这样做是为了像图像处理这样的事情(一次可以处理很多并行对象),那么最好将您的数据分解成个性化的数据块。也就是说,假设你想对一个较大的图像进行卷积,然后把它分成两半。然后,您可以使用“Fragmentimage”函数创建要单独处理的图像块,然后使用“MergeFragments”函数调用合并所有结果。所以你的片段看起来像:

class ThreadWorkFragment {
    <image type, like ushort>[] mDataArray;
    bool mDone;
}
类ThreadWorkFragment{
[]mDataArray;
布尔-梅隆;
}
在该片段周围放置一个锁(即,一个对象和片段的列表,每个对象和片段都有一个锁等等),这样当线程访问它的片段时,它最终可以声明它“完成”,释放锁,然后您可以有一个最终的合并函数,它只等待那些完成的布尔值被标记。这样,如果其中一个线程在设置“完成”之前死亡,并且您知道该线程已死亡,那么您也知道该线程没有完成其工作,您需要执行一些错误恢复;如果您只是等待连接发生,线程可能仍然会弄乱其片段


但是,基于您试图解决的问题,有很多这样的具体想法需要实现。

这真的很有趣,也很好-尽管我不确定您在使用ThreadStart ts=()=>DoWork(复制)编程时做了什么@这是一个lambda表达式。这是在C#3.0中创建委托的一种简单方法。