0

In my C# win form project, I read some data by web service. It takes a few time, so I have a thread for reading like this:

System.Threading.ThreadPool.QueueUserWorkItem((o) =>
{
    SMSCenter_RecievedMessages = (new SMSCenterGetMessages()).getMessages());

    this.BeginInvoke(new Action(() =>
    {
        if (SMSCenter_RecievedMessages != null && SMSCenter_RecievedMessages.Length != 0)
        {
            // some code
        }
    }));
});

after 2 days running, some time I get this exception:

Null Reference Exception was unhandled : Object Reference Not set to an instance of an object.

Is it possible that before creating a new of object, getMessage() function is accured? Because I did it by thread. what is the wrong by this code?

Thanks for any helping?

Elahe
  • 1,379
  • 2
  • 18
  • 34
  • At which line you are getting the exception ? coz I don't find Nullreference possibility in your current code. . . – Rohit Prakash Feb 21 '15 at 10:45
  • @RohitPrakash I got it in SMSCenter_RecievedMessages = (new SMSCenterGetMessages()).getMessages()); that will accure few times – Elahe Feb 21 '15 at 10:46
  • In that case, off course, SMSCenterGetMessages object is not being created at the time. Try using Parallel stacks to figure out the exact case. – Rohit Prakash Feb 21 '15 at 10:49
  • @RohitPrakash how is it possible that `new` does not instantiate a new object and results to a `null` instead? – zerkms Feb 21 '15 at 10:50
  • @zerkms, Douglous has explained it all. – Rohit Prakash Feb 21 '15 at 10:55
  • @RohitPrakash no they have not. Douglas explained possible race condition in next lines (which does not actually play well with what OP stated few comments above). So my question is still open - how do you think it's possible that `new` does not initialize an object? – zerkms Feb 21 '15 at 10:55
  • There are only rare cases where a class constructor can return `null` (http://stackoverflow.com/a/194671/1149773). It's unlikely that the OP is actually getting the `NullReferenceException` on that line (unless it's thrown from *within* the constructor). – Douglas Feb 21 '15 at 11:04

1 Answers1

2

One possible cause of your error is that SMSCenter_RecievedMessages is presumably declared as a class field. If your code snippet can be executed multiple times in succession (e.g. from a click event handler), then this could lead to race conditions.

Suppose that an event handler causes your code snippet to start getting executed. The background thread populates SMSCenter_RecievedMessages with a non-null value, and dispatches control to the UI thread. The UI thread evaluates SMSCenter_RecievedMessages != null to true.

In the meantime, another event handler had caused your code snippet to start getting executed again (concurrently). This time, getMessages() returns null; this is assigned to the same SMSCenter_RecievedMessages field and overrides the previous value.

In the meantime, the UI thread has continued execution, and attempts to evaluate SMSCenter_RecievedMessages.Length != 0. Since the field has now been set to null, a NullReferenceException ensues.

Douglas
  • 53,759
  • 13
  • 140
  • 188
  • OP stated that `SMSCenter_RecievedMessages = (new SMSCenterGetMessages()).getMessages());` is the line that causes a null reference exception. – zerkms Feb 21 '15 at 10:54
  • @zerkms: The clarification was stated in a comment after the original question had been posted. In the absence of further information, the race condition on the `SMSCenter_RecievedMessages` field is still the likeliest explanation. – Douglas Feb 21 '15 at 11:01
  • I agree that for the original question it would be the most possible explanation (if only we ignore the last lines, where OP also refers to `getMessages()` explicitly), but OP stated it's the `(new SMSCenterGetMessages()).getMessages())` expression that fails. Which I personally don't believe, but we have what we have :-) – zerkms Feb 21 '15 at 11:02
  • Thanks for your good idea, but I used Lock() for whole this code, that I think it solves this race condition. but the unhandled exception is accure yet. – Elahe Feb 21 '15 at 11:04
  • @Elahe: I would suggest making `SMSCenter_RecievedMessages` a local variable instead, so that different executions of your code would not conflict with each other. If you don't use the field elsewhere, then this should be sufficient. If you do use the field elsewhere, then the lock needs to be applied for all uses, which might lead to UI freezes or deadlocks. – Douglas Feb 21 '15 at 16:24