我有一行代码,我将大量参数传递给方法。
foreach(Asset asset in assetList)
{
asset.ContributePrice(m_frontMonthPrice, m_Vol, m_divisor, m_refPrice, m_type,
m_overrideVol, i, m_decimalPlaces, metalUSDFID, metalEURFID);
}
我真正想做的是每次调用此方法时都会生成一个新线程,以便更快地完成工作(有很多资产)。
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();
}
这一直困扰着我......为什么我不能将参数传递给线程.....它有什么区别?
我无法看到一种不会涉及大量重构的方法...... .......这是一个旧的应用程序,由于特征蠕变而逐个构建。 因此,代码本身很混乱,难以阅读/遵循。
我以为我已经确定了一个区域以节省一些时间并提高处理速度,但现在我已经用这个来打了一堵墙。
非常感谢任何帮助或建议。
干杯。
我正在使用.Net 3.5 .......我可以更新到.Net 4.0
答案 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);
}