none
Calling managed code form unmanaged code using a non managed thread RRS feed

  • Question

  • Hi,

    I have a non-managed thread that is polling some data and once gets into some state change it should call back into managed code, I was thinking of using Marshal::GetFunctionPointerForDelegate to execute on the managed code; at least that is was the plan, but I stated getting a fear is that on garbage collections thing will go bad because I am using a non-managed thread doing the polling, because to what I understand on garbage collections the managed threads are suspended while the garbage collection is being performed but an external non-managed thread would not be suspended will just continue and can be entangled on invalid states with the garbage collection, the only solution I have come about is to use something as IPC to send messages between both sides.

    Is my fear funded or is there some other mechanism to prevent this invalid behavior on the  Marshal::GetFunctionPointerForDelegate making a lock or translating the call to a managed thread?

    Hugo



    Tuesday, November 20, 2012 7:36 PM

Answers

  • Hello Hugo,

    1. >> because to what I understand on garbage collections the managed threads are suspended while the garbage collection is being performed but an external non-managed thread would not be suspended will just continue and can be entangled on invalid states with the garbage collection...

    1.1 This is not correct. Whether or not the managed threads are suspended (due to garbage collection or any other cause), this fact is transparent to any running code.

    1.2 As far as your unmanaged code is concerned, the call to the managed delegate is synchronous. Hence even if there is some suspension going on in managed code, the only effect this has on your unmanaged code is that it too is suspended until the managed code resumes.

    1.3 The overall effect is simply : delay, i.e. a slow down in performance.

    2. What you should be worried about is the garbage collection of the delegate object itself.

    2.1 For this you should make sure that the managed delegate is kept alive (and is not garbage collected pre-maturely) whenever the unmanaged code calls it.

    2.2 To do this, you can use the GCHandle class to hold the delegate alive until it is no longer needed.

    2.3 The following article shows you how this can be done :

    Delegates As Callbacks Part 2

    https://limbioliong.wordpress.com/2011/06/19/delegates-as-callbacks-part-2/

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    • Marked as answer by Hugo Rumayor Wednesday, November 21, 2012 1:49 PM
    Wednesday, November 21, 2012 6:53 AM

All replies

  • Take a look at gcroot (http://msdn.microsoft.com/en-us/library/481fa11f%28v=vs.80%29.aspx) for all your managed-in-unmanaged needs...one you get rid of the gcroot handle,you can keep things from being garbage collected by simply keeping the reference around.

    Tuesday, November 20, 2012 7:52 PM
  • Hi,

    I am not talking of the delegate beeing garbage collected, my fear is related of having unmanaged threads runing on mamaged code while a garbage collection is beeing performed.

    Tuesday, November 20, 2012 8:09 PM
  • Hello Hugo,

    1. >> because to what I understand on garbage collections the managed threads are suspended while the garbage collection is being performed but an external non-managed thread would not be suspended will just continue and can be entangled on invalid states with the garbage collection...

    1.1 This is not correct. Whether or not the managed threads are suspended (due to garbage collection or any other cause), this fact is transparent to any running code.

    1.2 As far as your unmanaged code is concerned, the call to the managed delegate is synchronous. Hence even if there is some suspension going on in managed code, the only effect this has on your unmanaged code is that it too is suspended until the managed code resumes.

    1.3 The overall effect is simply : delay, i.e. a slow down in performance.

    2. What you should be worried about is the garbage collection of the delegate object itself.

    2.1 For this you should make sure that the managed delegate is kept alive (and is not garbage collected pre-maturely) whenever the unmanaged code calls it.

    2.2 To do this, you can use the GCHandle class to hold the delegate alive until it is no longer needed.

    2.3 The following article shows you how this can be done :

    Delegates As Callbacks Part 2

    https://limbioliong.wordpress.com/2011/06/19/delegates-as-callbacks-part-2/

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    • Marked as answer by Hugo Rumayor Wednesday, November 21, 2012 1:49 PM
    Wednesday, November 21, 2012 6:53 AM
  • Thanks, 1.2 is what I was the response I was looking for, that the callback is guarded by a synchronization primitive so there would never be an issue of an unmanaged thread causing problems on managed code, the whole exersise in adding this callback was to try to make a more deterministic reading of push buttons form a Digital I/O board so I would not loose a button beeing pressed; so if the delegate call will block I would need to use another thread to make the call to managed code, so the polling thread would never be blocked;

    Wednesday, November 21, 2012 1:49 PM