Click here to Skip to main content
16,005,038 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
**Updated to actually make sense, I hope** Ok folks I am trying to tackle something here but it is over my head. Here is the idea I have a class library that raises events that I want to subscribe to from a winform. When the even is raised I want to use an object in the eventargs to update the form without dealing with a cast invoke (I have multiple threads going on) in the form code itself. Ultimately I found some code online that works but i'd like to write and extension method for it and I'm failing.

Original <slightly modified=""> working code:
C#
public delegate void StatusLogUpdated(object sender, StatusLoggerUpdatedEventArgs e);
public event StatusLogUpdated StatusChanged;



public void AddLog(LogItem logItem)
{
//Some internal stuff

StatusLogUpdated handler = StatusChanged;

if (handler != null)
{
   foreach (StatusLogUpdated singleCast in handler.GetInvocationList())
   {
      ISynchronizeInvoke syncInvoke = singleCast.Target as ISynchronizeInvoke;
      if ((syncInvoke != null) && (syncInvoke.InvokeRequired))
      {
          syncInvoke.Invoke(singleCast, new object[] { this, logEA });
      }
      else
      {
           singleCast(this, logEA);
      }
   }
}
}


Flawed Idea Code

C#
public static void SafeInvoke(this Delegate theDelegate, EventArgs e)
{
   Delegate handler = theDelegate;

   if (handler != null)
   {
      foreach (var singleCast in handler.GetInvocationList())
      {
         ISynchronizeInvoke syncInvoke = singleCast.Target as ISynchronizeInvoke;
         if ((syncInvoke != null) && (syncInvoke.InvokeRequired))
         {
            syncInvoke.Invoke(singleCast, new object[] { null, e });
         }
         else
         {
            singleCast(null, e); // compiler gripes with "'singleCast' is a                   
                                 // variable' but is used like a 'method'"
         }
      }
   }
}


I feel like I'm so close here but I can't seem to figure out what to do instead of the singleCast(null,e); Any thoughts are welcome, I am past my knowledge level. I'm not even fully sure of the ramifications of what I'm trying to do. I'm still pretty new to c# (and programming) so if my terms are off I apologize. Thanks in advance.
Posted
Updated 22-Jan-12 15:58pm
v7
Comments
Sergey Alexandrovich Kryukov 22-Jan-12 2:05am    
How can you talk about "without dealing with a cast", if you are trying to do a sequence of slowest dynamic cast "is" in a loop?! What is the purpose of this? Normally, the class derived from EventArgs is designed to avoid casts; sometimes, sender needs a cast though. As to the first sample, what is StatusLoggerUpdatedEventArgs? Can singleCast become null? What the declaring class does and why?

The purpose of iteration through InvocationList is not clear. I used to do it, for a special purpose (please see my article "Dynamic Method Dispatcher" if interested), but "I want to use an object in the eventargs to update the form" does not justify it. Normally, the whole list is invoked in one Invoke method. Same thing with invocation from a non-UI thread. Both things are much simpler in implementation.

Are you sure you know what do you wan to achieve? If you "found some code online" it would be good to understand what it does. At least show a link.

--SA
rleonard55 22-Jan-12 3:13am    
I appreciate you taking the time to respond but some of it isn’t necessary. I’m certain if you took the time to read it again you would see that I never actually said what you quote me as saying. I am trying to find a way to not need to deal with any invoke logic (I never brought up case) in the form itself but keep it all in the class library. I’m aware there might be unclear or incorrect ideas conveyed here. This is a ‘question’ not an article. As I said I am new and trying to learn, I acknowledge (as I did in the original post) this may be a bad idea and that I don’t fully understand the ramifications of what I am attempting to do. I’m just trying it.

StatusLoggerUpdatedEventArgs is just derived from generic EvengArgs so that I could attach my own class inside of it. “Can singleCast become null?”..? In the first example? How could it? It’s inside and dictated by the foreach. IE it wouldn’t even be hit unless there was something there, right?

I will take a look at your article and see what I can learn from it. Unfortunately I don’t have the link so I can’t provide it here. As for finding some code online…I’m not going to apologize for finding something (even if I don’t understand it) and trying to use and learn from it. I have gleaned a great deal this way. I brought it up here to try and learn more. There are a lot of very smart people out there and it seems you certainly count yourself among them. I’ll look into the ideas you mentioned and see what I can figure out but condescension isn’t necessary. No one deserves anything from anyone else here except for mutual respect.
Sergey Alexandrovich Kryukov 22-Jan-12 14:17pm    
Sorry, I made a mistake in first quote which I've just fixed. I types "case" instead of your "a cast". As to two other quotes, they are literally what you say. You will see it if you compare by yourself.
I think my questions to you remain valid. You did not explain to use some very essential things.
--SA
Sergey Alexandrovich Kryukov 22-Jan-12 14:22pm    
OK, here is the verdict on singleCast == null and the loop in invocation list. If singleCast is never null, the whole loop makes no sense as this is the only selected condition (InvokeRequired should be carried outside loop and is usually true; it is always true for the call from any non-UI thread). You should invoke the whole delegate instance at once: handler.Invoke.
--SA
rleonard55 22-Jan-12 21:10pm    
Are you confusing the “syncInvoke !=null” line with the singleCast object being used to iterate through the GetInvocationList? If not you have complely lost me with the “the whole loop makes no sense” bit.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900