3

I have a weird random NPE error when dealing with ManualResetEvent.WaitOne(). Here's my code.

I have a method that creates ManualResetEvent object and then it passes it down to the Windows Workflow Foundation (WWF) workflow instance as one of the dependency parameter (manualResetEvent) and then I go into manualResetEvent.WaitOne() API.

ManualResetEvent manResetEvt = new ManualResetEvent(false);

Dictionary<String, Object> wfArgs = new Dictionary<string, object>();
wfArgs["manualResetEvent"] = manResetEvt;

WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(MyWWFProcess), wfArgs);

instance.Start();
manResetEvt.WaitOne();

When the job is done within WWF, I simply call manualResetEvent.set().

if (this.manualResetEvent != null)
{
    this.manualResetEvent.Set();
}

All these compile well and while running, I see that the flow gets into the WWF as expected and the caller does wait on WaitOne() call too.

The moment the WWF invokes manualResetEvent.Set() to notify the caller, I see an NPE exception with the caller NOT WWF.

System.NullReferenceException: Object reference not set to an instance of an object.

I really don't know where this exception arises from. When I debug this code in VS IDE, all works well but only when with the application in the Release mode, I see this exception.

What am I doing wrong here?

JKK
  • 311
  • 1
  • 4
  • 15
  • possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) –  Apr 27 '15 at 14:55
  • Can you post the entire code of your class? Just seeing bits of it makes it harder to grasp. – Jason Evans Apr 27 '15 at 14:56
  • 1
    Sounds like it might be the code that's immediately following `manResetEvt.WaitOne()`? – James Thorpe Apr 27 '15 at 14:57
  • Andreas, when I run this code in debugger, it works just fine and only it fails with this exception only when I run with the application. – JKK Apr 27 '15 at 14:58
  • James, no. manualResetEvt.WaitOne() is the last line in the code. There is nothing after that line. After this, the method ends. As I mentioned above all works well in debugger. – JKK Apr 27 '15 at 14:59
  • Something must have called that method. Perhaps it's being thrown from there? Do you have a stack trace from the error? [`WaitOne`](https://msdn.microsoft.com/en-us/library/58195swd(v=vs.110).aspx) doesn't throw a NRE, so it shouldn't be that line that's throwing. If all else fails and you have no other info and are unable to debug, you need to start adding in some logging around the wait and whatever is calling this code etc to find out the exact point it's throwing the error. – James Thorpe Apr 27 '15 at 15:01
  • How does the workflow actually run? Is it in a separate application domain? Or on a remote server somewhere? Or is it *just* a separate thread? And why are you running the workflow asynchronously just to wait on it on the next line of code? Also, are you sure the code you pasted here is correct? I can't find any `Start` method on `WorkflowInstance`. – Luaan Apr 27 '15 at 15:03
  • It is in the same application domain and no remote server here. WWF always run on their own thread just as if you do ThreadPool.QueueWorkItem() and it is doing the same effect behind the scene. You can check out the Start() method details from MSDN: https://msdn.microsoft.com/en-us/library/system.workflow.runtime.workflowinstance.start%28v=vs.110%29.aspx – JKK Apr 27 '15 at 15:11
  • James, Actually I get the effect what I need with the current code if I suppress this error. So this tells me that somehow the manualResetEvent object becomes NULL after WWF sets it? – JKK Apr 27 '15 at 15:27

2 Answers2

0

I found the answer to my question. Based on James Thorpe suggestion, I printed the stack-trace from the exception and it turns out the application is sending a NULL data point when invoking this method and WaitOne() is not causing the NPE. When I ran the unit-test from VS IDE debugger, I passed in a good value hence no exception found. After fixing the caller method, all is working well. Thanks everyone who pitched in ideas to resolve this issue.

JKK
  • 311
  • 1
  • 4
  • 15
-1

You need to add the object to the dictionary

Dictionary<String, Object> wfArgs = new Dictionary<string, object>();
wfArgs.Add("manualResetEvent", manResetEvt);
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • It is added via this line: wfArgs["manualResetEvent"] = manResetEvt; – JKK Apr 27 '15 at 15:15
  • [Here's the code](http://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs,172) showing the indexer calling `Insert` internally - ie this will add it. – James Thorpe Apr 27 '15 at 15:16
  • JKK : If the key "manualResetEvent] isn't in the dictionary an exception will occur. – jdweng Apr 27 '15 at 17:09
  • 1
    @jdweng that is not true: https://msdn.microsoft.com/en-us/library/9tee9ht2(v=vs.110).aspx *If the specified key is not found, a get operation throws a KeyNotFoundException, and **a set operation creates a new element with the specified key.*** Secondly, if we have generics, why don't you use them to type the value to `ManuelResetEvent`? –  Apr 28 '15 at 06:15
  • @AndreasNiedermair Regarding the type - [`CreateWorkflow`](https://msdn.microsoft.com/en-us/library/ms594871(v=vs.110).aspx) takes a `Dictionary` as a parameter, as per the OP code (I assume there may be other parameters with other types that aren't shown in the question). I agree with you on the setting/inserting of the key though... – James Thorpe Apr 28 '15 at 08:40