views:

59

answers:

4

Scenario

I have a line of code whereby I pass a good number of parameters into a method.

CODE as described above

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

What I really want to do...

What I really want to do is spawn a new thread everytime I call this method so that it does the work quicker (there are a lot of assets).

Envisaged 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();
 }

ISSUES

This is something which has always bothered me......why can't I pass the parameters into the thread.....what difference does it make?

I can't see a way around this that won't involve lots of refactoring...... .......This is an old application, built piece by piece as a result of feature creep. Therefore, the code itself is messy and hard to read/follow.

I thought I had pinpointed an area to save some time and increase the processing speed but now I've hit a wall with this.

SUGGESTIONS?

Any help or suggestions would be greatly appreciated.

Cheers.

EDIT:

I'm using .Net 3.5.......I could potentially update to .Net 4.0

+3  A: 

If you're using C# 3, the easiest way would be:

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();
}

You need to take a "local" copy of the asset loop variable to avoid weird issues due to captured variables - Eric Lippert has a great blog entry on it.

In C# 2 you could do the same with an anonymous method:

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();
}

In .NET 4 it would probably be better to use Parallel.ForEach. Even before .NET 4, creating a new thread for each item may well not be a good idea - consider using the thread pool instead.

Jon Skeet
+2  A: 

Spawning a new thread for each task will most likely make the task run significantly slower. Use the thread pool for that as it amortizes the cost of creating new threads. If you're on .NET 4 take a look at the new Task class.

If you need to pass parameters to a thread when starting it, you must use the ParameterizedThreadStart delegate. If you need to pass several parameters, consider encapsulating them in a type.

Brian Rasmussen
+2  A: 

You could use ParameterizedThreadStart. You'll need to wrap all of your parameters into a single object. (Untested code below).

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);
} 
Paul Kearney - pk