C#Thread Spawn参数传递

时间:2010-05-13 16:57:10

标签: c# multithreading

方案

我有一行代码,我将大量参数传递给方法。

如上所述的CODE

foreach(Asset asset in assetList)
{
asset.ContributePrice(m_frontMonthPrice, m_Vol, m_divisor, m_refPrice, m_type,
 m_overrideVol, i, m_decimalPlaces, metalUSDFID, metalEURFID);
 }

我真正想做的事情......

我真正想做的是每次调用此方法时都会生成一个新线程,以便更快地完成工作(有很多资产)。

设想的CODE

 foreach(Asset asset in assetList)
{
     Thread myNewThread = 
     new Thread(new ThreadStart(asset.ContributePrice  (m_frontMonthPrice, m_Vol,
      m_divisor, m_refPrice, m_type, m_overrideVol, i, m_decimalPlaces, metalUSDFID,   
      metalEURFID)));

  myNewThread.Start();
 }

问题

这一直困扰着我......为什么我不能将参数传递给线程.....它有什么区别?

我无法看到一种不会涉及大量重构的方法...... .......这是一个旧的应用程序,由于特征蠕变而逐个构建。 因此,代码本身很混乱,难以阅读/遵循。

我以为我已经确定了一个区域以节省一些时间并提高处理速度,但现在我已经用这个来打了一堵墙。

SUGGESTIONS?

非常感谢任何帮助或建议。

干杯。

编辑:

我正在使用.Net 3.5 .......我可以更新到.Net 4.0

3 个答案:

答案 0 :(得分:3)

如果您使用的是C#3,最简单的方法是:

foreach(Asset asset in assetList)
{
    Asset localAsset = asset;
    ThreadStart ts = () => localAsset.ContributePrice (m_frontMonthPrice, m_Vol,
        m_divisor, m_refPrice, m_type, m_overrideVol, i, 
        m_decimalPlaces, metalUSDFID, metalEURFID);
    new Thread(ts).Start();
}

你需要获取asset循环变量的“本地”副本,以避免由于捕获的变量引起的奇怪问题--Eric Lippert上有great blog entry

在C#2中,您可以使用匿名方法执行相同的操作:

foreach(Asset asset in assetList)
{
    Asset localAsset = asset;
    ThreadStart ts = delegate { localAsset.ContributePrice(m_frontMonthPrice,
        m_Vol, m_divisor, m_refPrice, m_type, m_overrideVol, i, 
        m_decimalPlaces, metalUSDFID, metalEURFID); };
    new Thread(ts).Start();
}

在.NET 4中,使用Parallel.ForEach可能会更好。甚至在.NET 4之前,为每个项目创建一个新线程可能不是一个好主意 - 考虑使用线程池。

答案 1 :(得分:2)

为每个任务生成一个新线程很可能会使任务运行速度明显变慢。使用线程池,因为它会分摊创建新线程的成本。如果您使用的是.NET 4,请查看the new Task class

如果需要在启动时将参数传递给线程,则必须使用ParameterizedThreadStart delegate。如果需要传递多个参数,请考虑将它们封装在一个类型中。

答案 2 :(得分:2)

您可以使用ParameterizedThreadStart。您需要将所有参数包装到单个对象中。 (下面未经测试的代码)。

struct ContributePriceParams
{
    public decimal FrontMonthPrice;
    public int Vol;
    //etc
}

//...

 foreach(Asset asset in assetList)  
{  
     ContributePriceParams pStruct = new pStruct() {FrontMonthPrice = m_frontMonthPrice, Vol = m_vol};
     ParameterizedThreadStart pStart = new ParameterizedThreadStart(asset.ContributePrice);
     Thread newThread = new Thread(pStart);
     newThread.Start(pStruct);
}