0

My class I'm writing is using multi threads and I have this extension method I have created for my class to raise events in a thread safe way.

static class MultiThreadHelper
{
    public static object Raise(this MulticastDelegate eventToRaise, object sender, EventArgs e)
    {
        object retVal = null;

        MulticastDelegate threadSafeMulticastDelegate = eventToRaise;
        if (threadSafeMulticastDelegate != null)
        {
            foreach (Delegate d in threadSafeMulticastDelegate.GetInvocationList())
            {
                var synchronizeInvoke = d.Target as ISynchronizeInvoke;
                if ((synchronizeInvoke != null) && synchronizeInvoke.InvokeRequired)
                {
                    retVal = synchronizeInvoke.EndInvoke(synchronizeInvoke.BeginInvoke(d, new[] { sender, e }));
                }
                else
                {
                    retVal = d.DynamicInvoke(new[] { sender, e });
                }
            }
        }

        //Return the value of the event invocation or null if none.
        return retVal;
    }
}

When my form tries to close a lingering thread is still trying to report back and it raises an event that no longer has a handler.

I end up getting the following error...

enter image description here

What kind of check can I run before that line error occurs? Is there anything else I can do or different approach I can take to resolve the issue?

Arvo Bowen
  • 4,524
  • 6
  • 51
  • 109

1 Answers1

2

My first thought would be that ManifestBuilder is not unsubscribing from the delegate when it is being closed. Make sure you unsubscribe using the -= syntax.

Scott Baldwin
  • 431
  • 2
  • 10
  • I was doing that in the FormClosing event on ManifestBuilder. But I did it as the last action in the event block. When I put it as the first action in the event block it seemed to elevate the issue. I think my mistake was making user I unsubscribe BEFORE I dispose of the class object... Though I don't see why that would matter. – Arvo Bowen Jun 12 '16 at 15:14
  • Digging into it more... In the FormClosing event I would try to call a method of the class that would create a new thread. Then as soon as that new thread was created I would unsubscribe. Then... once the thread was finished it would send an event (thinking there was one subscribed). Is there any way to check if ANY subscriptions are alive when dealing with multi-threading? My issue was simple, subscribe to event -> force thread to send event on a timer -> unsubscribe -> event fires thinking there is a subscription but has no subscription to go to. – Arvo Bowen Jun 12 '16 at 15:52
  • On further inspection of your code, I would look into where you getting the reference to eventToRaise that you are passing into your Raise method. The only thing I can think is that you are assigning that variable at a point before the form is disposed, and the event unsubscribed, and then using it after the form has been disposed. – Scott Baldwin Jun 13 '16 at 09:14
  • Yea, that seems to be exactly what is happening... The issue is that "variable"/object that is being passed in will always exist. So checking for null is a bust. I never did find a way to see if the event had any subscriptions or not so I just simply put that call in a try-catch block. ;) – Arvo Bowen Jun 13 '16 at 12:56
  • A better way of solving this (rather than try-catch) would be to ensre that the control outlives the thread. Take a look at this stackoverflow question http://stackoverflow.com/questions/1874728/avoid-calling-invoke-when-the-control-is-disposed, they had a similar problem. – Scott Baldwin Jun 14 '16 at 07:09