views:

63

answers:

2

As the code shows below, I'm creating a thread in a foreach loop and running them at a later time, however when I run the thread I get the "object reference not set to an instance of an object" error. I suspect this is a closure problem, but it seems like i'm doing everything i should be to avoid that here by creating a local copy of the value. How can this code be corrected to accomplish the creation of a threads, then at a later time, allowing for the methods to be invoked (threads started)?

foreach (ObjWithDelegateToCreateTrdFrom item in queryResult)
{
    // Capture object state    
    ObjWithDelegateToCreateTrdFrom capturedValue = item;

    // Create thread from object
    Thread thread = new Thread(() =>
    {
        capturedValue.Method.Invoke(capturedValue.paramsArray)
    });

    // Add thread to temp thread list
    trdList.Add(thread);
}
+1  A: 

Try this:

foreach (ObjWithDelegateToCreateTrdFrom item in queryResult)
{
    if (item == null)
    {
        throw new InvalidOperationException("Item is null");
    }

    if (item.Method == null)
    {
        throw new InvalidOperationException("Item.Method is null");
    }

    if (item.paramsArray == null)
    {
        throw new InvalidOperationException("Item.paramsArray is null");
    }

    // Create thread from object
    Thread thread = new Thread(() =>
    {
        capturedValue.Method.Invoke(capturedValue.paramsArray)
    });

    // Add thread to temp thread list
    trdList.Add(thread);
}

When this doesn't solve your problem, please give us a stack trace with more information.

Steven
Check out my solution below, it's more accurate imo.
Grozz
@Stepen - thanks for the code sample! I'm implementing your solution within the lambda body.
Joel B
+2  A: 

Check the values of:

  1. capturedValue
  2. capturedValue.Method
  3. capturedValue.paramsArray

in the lambda body, i.e. at the moment when thread is executed.

Even if they are not null at the moment you created the thread, they could be set to null inbetween the time of you initializing the thread object and the time runtime decides to execute it.

Grozz
Joel B