我现在正试图通过使winform应用程序成为多线程来提高它的性能。目前这个类看起来是这样的:
public class MainClass
{
List<DataItem> data; //thousands of DataItem, but each is independent
//and a lot of non-thread-safe variables here,variable1 variable2 ...
public void Go()
{
data.ForEach(item => DealWithDataItem(item));
}
public void DealWithDataItem(DataItem item)
{
//costs really long time here
Step1(item);
Step2(item); //and a lot of StepN(item)
}
public void StepN(DataItem item)
{
//variable1 = blabla
//variable2 = blabla ..etc
}
}我想对每个DataItem使用ThreadPool。
data.ForEach(item => ThreadPool.QueueUserWorkItem( s => DealWithDataItem(item) ));但是有这么多非线程安全的变量!我不能在某些方法中声明它们,因为它在StepN方法之间共享。而且很难让它们都是线程安全的!我做错什么了吗?有什么好的解决方案吗?谢谢!
发布于 2010-12-01 19:30:31
尝试使用ParallelEnumerable.AsParallel。
data.AsParallel.ForEach(DoWork);它将根据处理器/核心的数量自动创建线程。唯一的问题是它包含在Framework4.0中。有关PLINQ的更多信息。(正如andras评论的那样:对于Framwork3.5,它可以作为独立的Reactive Extensions (Rx)使用)
更新:正如0xA3所说,强烈建议重构代码,使每一项都有自己的计算变量。我建议您将计算逻辑提取到DataItem中
或者创建像“计算器”这样的特殊类,它将做所有的工作,所以DataItem只存储数据,计算的逻辑将包含在计算器类中。
data.AsParallel.ForEach(x=> new Calculator().DoWork(x));其中Calculator类如下所示
class Calculator
{
// variables here
void DoWork(DataItem item)
{
Step1(item);
Step2(item);
// ...
// StepN(item);
}
}发布于 2010-12-01 19:30:50
也许最好的方法是重构你的代码,这样你就可以去掉在不同数据项之间共享的所有字段。
更改(或子类) DataItem类,使其包含用于操作dataItem的所有相关数据和方法,以便您的代码更改为如下所示:
public void DealWithDataItem(DataItem item)
{
item.Step1(); // does not change the state of `this`
// and only changes variables that are private to `item`
item.Step2(); // and a lot of StepN(item)
}发布于 2010-12-02 01:43:30
因为每个DataItem都是独立的,所以将工作移到一个新的DataItem worker方法中,让每个实例自己处理:
public class MainClass
{
List<DataItem> data; //thousands of DataItem, but each is independent
public void Go()
{
data.ForEach(item => ThreadPool.QueueUserWorkItem(s => s.DealWithSelf()));
}
}
public class DataItem
{
//and a lot of non-thread-safe variables here,variable1 variable2 ...
void DealWithSelf()
{
//costs really long time here
Step1(item);
Step2(item); //and a lot of StepN(item)
}
public void StepN(DataItem item)
{
//variable1 = blabla
//variable2 = blabla ..etc
}
}https://stackoverflow.com/questions/4323750
复制相似问题