Handling an Event Raised in a Separate DLL - c#

I am having some issues with handling an event that I am raising in a separate DLL in a separate exe. I have a class that subscribes to the event in another DLL. When I raise the event, by the time I get to the event handling, the event handler is null since the object that subscribed to it exists in separate call stack. Is there a clean way to handle something like this?
Public class B is in another dll on another executable (same solution) than Class A.
public static class CustomEvent
{
public static event EventHandler<CustomEventArgs> eventHandler;
public static void Raise(CustomEventArgs args)
{
// When class B raises the event. The eventHandler here is null.
// Meaning it doesn't know that Class A has subscribed to the event.
EventHandler<CutomEventArgs> handler = eventHandler;
if(handler != null)
{
eventHandler(typeof(CustomEvent), args);
}
}
}
public class A
{
public class A ()
{
CustomEvent.eventHandler += HandleEvent;
}
public class B
{
public void Function()
{
CustomEvent.Raise(new CustomEventArgs());
}
}

Related

How to catch event firing from class constructor

Here is an example...
public class CodeGenerator
{
public delegate void GeneratorCalculatorEventHandler(decimal Fond);
public event GeneratorCalculatorEventHandler eventName;
public CodeGenerator()
{
eventName?.Invoke(0);
}
}
How could I catch the event? If I do this:
CodeGenerator CodeGen = new CodeGenerator();
CodeGen.eventName += CodeGen_eventName;
The event is fired when the handler is not subscribed to it yet. Is it possible to subscribe to an event on initialiazation?
As the comments said, this is a bad code smell. It sounds like you're doing something very unusual here and you should consider trying to find a different way to solve your problem.
One of the reasons it smells bad is: if the calling code knows to pass the handler to the constructor, then that code already knows that the constructor is being invoked. The caller could simply invoke the handler itself with the constructed instance! Events are typically for situations where something happens that the handler could not predict or control, like the user clicking a button.
I would not pass the handler to the constructor, were I in your situation. I would use a static event.
You should pass the handler to the constructor and attach it to the event, something like:
public class CodeGenerator
{
public delegate void GeneratorCalculatorEventHandler(decimal Fond);
public event GeneratorCalculatorEventHandler eventName;
public CodeGenerator(GeneratorCalculatorEventHandler listener)
{
eventName += listener;
eventName?.Invoke(0);
}
}
public class Test
{
public Test()
{
CodeGenerator gen = new CodeGenerator((sen) => { return; });
}
}

PropertyChangedEventHandler event only handled once

I use OnPropertyChanged("property"); to raise the event via a setter of a property.
Class1.xaml.cs:
public Class1()
{
InitializeComponent();
Class2.PropertyChanged += delegate
{
// do stuff
};
}
In Class2.cs I have the following:
public static event PropertyChangedEventHandler PropertyChanged = delegate { };
public static void OnPropertyChanged(string property)
{
PropertyChanged(null, new PropertyChangedEventArgs(property));
}
The delegate in Class1 executes one time. Class2 works as expected. I checked this with breakpoints.
What happens in order is:
Class2 fires event
Class1 handles event
Class2 fires event
Class2 fires event
Also, when I remove = delegate { } the second time the handler is null.
How can I handle the event in Class1 every time it fires in Class2?
EDIT:
My project structure is the following:
App
Location of Class1, main project.
App.Shared
Location of Class2, shared logic for main and background project.
App.Background
Background project for
IBackgroundTask. Here I call OnPropertyChanged("property").

C# Calling a function on a Form from an Event, outside of this Form class

This has been asked probably many times, but looking through all the other questions I still was not able to solve my issue. I want to update a Datagridview on a form using an update function on this form. The Update function is called by a subscriber.
Overview:
static class MainClass
{
static void Main()
{
// The Main form is called.
MainForm = new frmMain();
Application.Run(MainForm);
//Application.Run(new frmMain());
}
}
A Delegate
public delegate void Delagate_UpdateDataView();
The subscriber that subscribed to publisher that fires an event every 500 ms.
public class SubscriberFrmMain
{
// Constructor
public SubscriberFrmMain()
{
}
// Subscribe to the Publisher
public void Subscribe(PublisherTimedEvent mUpdateHMIData)
{
//attach listener class method to publisher class delegate object
mUpdateHMIData.TickUpdateHMIData += UpdateHMIData;
}
// The Event, fired when the Publisher raises an event.
private void UpdateHMIData(PublisherTimedEvent mUpdateHMIData,EventArgs e)
// Calling the Update function on the Form MainForm.
{
MainClass.MainForm.Process_UpdateDataView(new
Delagate_UpdateDataView(MainClass.MainForm.UpdateDataView));
}
}
The Update function in the Form
public void Process_UpdateDataView(Delagate_UpdateDataView update)
{
update();
}
public void UpdateDataView()
{
try
{
TagTableAdapter.Fill(uDataSet.PLC_Tag);
}
catch
{
}
}
Updating the TagTableAdapter manually works without any problem. Updating using the subscriber does nothing.
Probably there are easier ways to achieve this but I would like to use this type of construction also for other parts of the program.
Thanks for your suggestions.
Event's can only be risen from inside the class. If you could do that it would defeat the purpose of events.You can subscribe to this event from other class tho.
public event EventHandler someEvent;
EventContainer obj = new EventContainer();
obj.someEvent += handler;
where handler is a method according to the signature of someEvent. One is able to subscribe to the event from the outside just fine, but it can only be risen from inside the class defining it.

Raise event of other class library in c#

I have two class libraries say A and B. A has reference of B. so I can call any function of B. But now the need is, I want to raise event(or function; actually just want to send a little info) of A from B. I cant add reference because of circular dependency. Is there any way to do this ?
please give me code sample; how to register and call
Thanks
Define event in class B (you can use one of Action delegates for event):
public class B
{
public event Action<int> SomethingHappened; // define event
private void Something()
{
if (SomethingHappened != null) // check if somebody subscribed
SomethingHappened(42); // raise event and pass data
}
}
And subscribe to that event in class A:
public class A
{
private B _b;
public A(B b)
{
_b = b;
_b.SomethingHappened += SomethingHappenedWithB; // subscribe
}
private void SomethingHappenedWithB(int data)
{
// handle event, use data
}
}
Consider reading C# Events Tutorial

C# How to create a Singleton that publishes events & Classes that subscribe?

Goal: Have a singleton publish events and allow any class to subscribe/listen to those events
Problem: I cannot figure out how to do this. The code below is illegal but it purveys what I'm trying to do
TransmitManager Class - Publisher
//Singleton
public sealed class TransmitManager
{
delegate void TransmitManagerEventHandler(object sender);
public static event TransmitManagerEventHandler OnTrafficSendingActive;
public static event TransmitManagerEventHandler OnTrafficSendingInactive;
private static TransmitManager instance = new TransmitManager();
//Singleton
private TransmitManager()
{
}
public static TransmitManager getInstance()
{
return instance;
}
public void Send()
{
//Invoke Event
if (OnTrafficSendingActive != null)
OnTrafficSendingActive(this);
//Code connects & sends data
//Invoke idle event
if (OnTrafficSendingInactive != null)
OnTrafficSendingInactive(this);
}
}
Test Class - Event Subscriber
public class Test
{
TrasnmitManager tm = TransmitManager.getInstance();
public Test()
{
//I can't do this below. What should my access level be to able to do this??
tm.OnTrafficSendingActive += new TransmitManagerEventHandler(sendActiveMethod);
}
public void sendActiveMethod(object sender)
{
//do stuff to notify Test class a "send" event happend
}
}
You shouldn't need to make the events static.
public event TransmitManagerEventHandler OnTrafficSendingActive;
public event TransmitManagerEventHandler OnTrafficSendingInactive;
Either your events have to be instance members or you have to address them as static.
TransmitManager.OnTrafficSendingActive +=...
OR
public event TransmitManagerEventHandler OnTrafficSendingActive;
...
TransmitManager.Instance.OnTrafficSendingActive+=...
Also: use EventHandler as your event delegate. Consider making a custom arguments class and pass the status to just one event instead of multiple events. This will let you pass status messages as well.

Categories

Resources