首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过多线程提高性能

通过多线程提高性能
EN

Stack Overflow用户
提问于 2010-12-01 19:16:10
回答 4查看 2.1K关注 0票数 2

我现在正试图通过使winform应用程序成为多线程来提高它的性能。目前这个类看起来是这样的:

代码语言:javascript
复制
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

代码语言:javascript
复制
data.ForEach(item => ThreadPool.QueueUserWorkItem( s => DealWithDataItem(item) ));

但是有这么多非线程安全的变量!我不能在某些方法中声明它们,因为它在StepN方法之间共享。而且很难让它们都是线程安全的!我做错什么了吗?有什么好的解决方案吗?谢谢!

EN

回答 4

Stack Overflow用户

发布于 2010-12-01 19:30:31

尝试使用ParallelEnumerable.AsParallel

代码语言:javascript
复制
data.AsParallel.ForEach(DoWork);

它将根据处理器/核心的数量自动创建线程。唯一的问题是它包含在Framework4.0中。有关PLINQ的更多信息。(正如andras评论的那样:对于Framwork3.5,它可以作为独立的Reactive Extensions (Rx)使用)

更新:正如0xA3所说,强烈建议重构代码,使每一项都有自己的计算变量。我建议您将计算逻辑提取到DataItem中

或者创建像“计算器”这样的特殊类,它将做所有的工作,所以DataItem只存储数据,计算的逻辑将包含在计算器类中。

代码语言:javascript
复制
data.AsParallel.ForEach(x=> new Calculator().DoWork(x));

其中Calculator类如下所示

代码语言:javascript
复制
class Calculator
{
   // variables here

  void DoWork(DataItem item)
  {
     Step1(item);
     Step2(item);
     // ...
     // StepN(item);
  }
}
票数 3
EN

Stack Overflow用户

发布于 2010-12-01 19:30:50

也许最好的方法是重构你的代码,这样你就可以去掉在不同数据项之间共享的所有字段。

更改(或子类) DataItem类,使其包含用于操作dataItem的所有相关数据和方法,以便您的代码更改为如下所示:

代码语言:javascript
复制
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)
}
票数 0
EN

Stack Overflow用户

发布于 2010-12-02 01:43:30

因为每个DataItem都是独立的,所以将工作移到一个新的DataItem worker方法中,让每个实例自己处理:

代码语言:javascript
复制
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
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4323750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档