none
Exceptions raised in Control.MarshaledInvoke - here is a possible cause RRS feed

  • Question

  • I've got a .NET 4.0 WinForms application that intermittently experiences exceptions in Control.MarshaledInvoke.

    I've seen various exceptions including System.ArgumentOutOfRangeException.

    A similar bug is reported here: http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/e23ee825-4992-4740-a438-04415c9b27f4

    So I looked at the source code for .Net 2.0 that I downloaded with .net mass downloader a long time ago.

    I see that in Control.MarshalledInvoke, access to "threadCallbackList" instance variable is synchronized using "this", yet in InvokeMarshalledCallback, access to "threadCallbackList" is syncronized via "threadCallbackList".  I think the inconsistency in syncronization is the likely cause.

    Can someone at microsoft comment on this?

    Thursday, November 29, 2012 2:31 PM

Answers

  • It's very likely that the exception is actually thrown by the invoked code. The marshaled invoked mechanism propagates it back to the background thread. Unfortunately in doing so it appears that it loses the real stack trace.

    If possible add some exception handling in the invoked code, this should give you the real stack trace. Alternatively try using BeginInvoke instead of Invoke, this will trigger the winforms exception dialog and it will show the real stack trace.

    Thursday, November 29, 2012 10:21 PM
    Moderator

All replies

  • "WinForms application that intermittently experiences exceptions in Control.MarshaledInvoke."

    What exception? Do you happen to have a stack trace?

    "I see that in Control.MarshalledInvoke, access to "threadCallbackList" instance variable is synchronized using "this", "

    That part seems fine to me, the lock (this) is to prevent multiple threads from creating multiple queues, it's needed first time Invoke/BeginInvoke is called on a control. After that the code locks on the callback list to prevent multiple threads from using the queue at the same time.

    I think I've seen some weird behavior in Invoke a long time ago but I didn't look closely at the problem back then. If you can provide more informations about the exceptions you are seeing perhaps I can take another look.

    Thursday, November 29, 2012 3:25 PM
    Moderator
  • Mike, upon reviewing the code, I concur with your assessment regarding lock(this).  Right now I can't see anything else in MarshaledInvoke that might throw ArgumentOutOfRangeException

    Note that this call is executing on a background thread as trigger by System.Threading.Timer.

    Control is an instance of DataGridView.  This occurs very very rarely. 

    Here is the stack trace: 

    Unhandled Execption: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index
       at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
       at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
       at Dashboard.IntervalDataTableBinding.SmartInvoke(Control C, Action Mthd) in xxxxxxxxx.vb
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean IgnoreSyncCtx)
       at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
       at System.Threading.ThreadPoolWorkQueue.Dispatch()
       at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

    • Edited by sevzas Thursday, November 29, 2012 8:55 PM
    Thursday, November 29, 2012 8:45 PM
  • I would add some tests for a null objects.  It is poosible the calback object wasn't intiallized with a constructor, or got destroy some place in the code.

    jdweng

    Thursday, November 29, 2012 9:57 PM
  • I'm not clear on which object to test for null.  Do you mean test Mthd object in my SmartInvoke?  Even if Mthd were null, how could that cause a ArgumentOutOfRangeException?

    Thursday, November 29, 2012 10:07 PM
  • It's very likely that the exception is actually thrown by the invoked code. The marshaled invoked mechanism propagates it back to the background thread. Unfortunately in doing so it appears that it loses the real stack trace.

    If possible add some exception handling in the invoked code, this should give you the real stack trace. Alternatively try using BeginInvoke instead of Invoke, this will trigger the winforms exception dialog and it will show the real stack trace.

    Thursday, November 29, 2012 10:21 PM
    Moderator
  • A null object is normally -1.  the error message said the following:

    Index was out of range. Must be non-negative and less than the size of the collection.

    I suspect the problem is occuring in one of your event handlers and you need to check the passed parameters to make sure they are not null.


    jdweng

    Thursday, November 29, 2012 10:31 PM
  • Mike:

    You've provided very useful info and a very reasonable explanation.  I will modify my code to catch, log and rethrow the exception.

    Joel:

    I still don't quite understand "A null object is normally -1".  Can you provide an example where a null object can cause the ArgumentOutOfRangeException exception to be raised?

    Friday, November 30, 2012 12:54 PM
  • I don't believe the issue is with Control.MarshaledInvoke. That may be where the exception is being realized, but I don't think any of the lock() statements you mention have anything to do with it.

    MarshaledInvoke doesn't directly throw any ArgumentExceptions, which means that something happened previously. As Mike mentions, it is likely in the method being invoked or in a code path that the invoked method takes.

    In addition to what the others have mentioned, I would suggest attaching a debugger debugging and breaking on 1st chance System.ArgumentExceptions. That should show you the culprit.

    Hope this helps,

    Keith Fink [MSFT]


    Keith Fink Microsoft

    Tuesday, December 4, 2012 10:00 PM
  • Keith -

    Your thoughts are inline with Mike and Joel.  I've instrumented the invoked code with additional logging and I'm waiting patiently for the problem to re-occur.

    Wednesday, December 5, 2012 2:05 PM
  • One of these errors occurred earlier today, caused by this exception which is triggered in my code:

    System.InvalidOperationException: Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.

    So I need to figure out what's causing this.

    Wednesday, December 19, 2012 2:36 PM