Raising event inside event - c#

I am trying to get an event to trigger once the code resulting from the trigger of another event finished working. To me, this means that I have to trigger the second event just at the end of said code.
The first event, here, is directly taken from the Vimba Camera API I'm using, and it works perfectly fine. I read a few things on how to call an event properly (particularly the first anwer here), but I can't get my second event to run properly. I probably misunderstood something, but what ?
Here is a pseudo-code version of what I wrote :
public partial class Form1 : Form
{
public delegate void SecondEventHandler(int[] myData);
public event SecondEventHandler SomethingHappened;
//Doing a lot of things irrelevant here
myObj.OnFirstEvent += new Obj.OnFirstEventHandler(this.OnFirstEvent);
private void OnFirstEvent(Data data)
{
//Doing things, and preparing myData
SomethingHappened += new SecondEventHandler(HandleSomethingHappened);
}
void HandleSomethingHappened(int[] myData)
{
//Working with myData
}
}

If you want to raise methods attached to second event:
private void OnFirstEvent(Data data)
{
//Doing things, and preparing myData
var h = SomethingHappened;
if(h != null)
h(pass your int[] parameter)
}

Actually, the easiest yet the cleanest way to achive this is called continuation-passing-style. OnFirstEvent(Data data) should become OnFirstEvent(Data data, Action<int[]> continuator). Whenever it is not null, your code calls it.
However I do warn you: don't let it grow and spread all over your code. It's hard to debug and maintain from a long-term perspective. If you'd expect such an approach to be used extensively, then take a look in reactive extensions.

Related

How to subscribe to and handle Windows Event Log Entries from a specific Source

I want to create a program that subscribes to the Windows Application event log and raises an event when an event log entry is written for a specific source.
I have been following this Microsoft code snippet which has been very helpful, however, I have a couple of questions about it:
I'm having trouble understanding the purpose of the static AutoResetEvent object in this example. In my testing, the event handler fires properly without it, however, I'd like to know if there's an underlying issue I'm not seeing by omitting it.
Is there any way to only raise an event when an entry is written to a specific source. I know I can just look at the source in the event handler, but it seems wasteful to me to enter the event handler when we don't need to.
Here is my code. I have been testing it by concurrently creating test events with different Source names in a Powershell session. Any suggestions for improvements would be greatly appreciated.
class Program {
static string eventLogSource = "testEventLogEvent";
public static void Main() {
EventLog myNewLog = new EventLog("Application", ".", eventLogSource);
try {
myNewLog.EntryWritten += new EntryWrittenEventHandler(MyOnEntryWritten);
myNewLog.EnableRaisingEvents = true;
Console.ReadKey();
} finally {
myNewLog.Dispose();
}
}
public static void MyOnEntryWritten(object source, EntryWrittenEventArgs e) {
Console.WriteLine("In event handler");
if (e.Entry.Source.Equals(eventLogSource)) {
Console.WriteLine(e.Entry.Message);
}
}
}

EventHandler not being called despite InvocationList containing the subscribing method C#

I am developing a MEF application. I am using a plugin as a publisher and another as a subscriber. For the current issue I guarantee that both plugin instances are active. On the subscriber I subscribe to the event and on the publisher I iterate over the invocation list and call the BeginInvoke to raise the event asynchronously as so:
Publisher:
public class BackchannelEventArgs : EventArgs {
public string Intensity { get; }
public BackchannelEventArgs(string intensity) {
this.Intensity = intensity;
}
}
public class Publisher {
public event EventHandler<BackchannelEventArgs> BackchannelEvent = delegate { };
private void BackchannelEventAux(string bcintensity) {
Plugin.LogDebug("BACKCHANNEL EVENT, sending to " + BackchannelEvent.GetInvocationList().Length + " subscribers: " + bcintensity);
var args = new BackchannelEventArgs(bcintensity);
foreach (EventHandler<BackchannelEventArgs> receiver in BackchannelEvent.GetInvocationList()) {
receiver.BeginInvoke(this, args, null, null);
}
}
}
Subscriber (relevant snippet, the Init is being called by a pluginsManager in which I can see the logs):
class Subscriber {
public void Init(){
LogInfo("Before subscribing");
publisher.BackchannelEvent += HandleBackchannelEvent;
LogInfo("After subscribing");
}
private void HandleBackchannelEvent(object sender, BackchannelEventArgs e) {
LogDebug("Handle Backchannel!");
}
}
Now, the Log you see on the event handler is not called at all. I have 4 other events that follow the same structure and somewhat this event in particular is not being called (I can see the logs on the other events). The other plugins follow the exact same structure.
Already tried:
Call synchronously BackchannelEvent(this, args) but the results are the same;
Subscribe this same event on the other plugins as well but the issue remains on this single event (and not on the others who follow the same structure).
I hope you can give me some help on this.
Thank you
Edit: The shown code is a snippet. The Init method is being called by the pluginsManager. I have put a log before the subscribing call and I can confirm that I am indeed subscribing.
Edit2: The number of elements in the InvocationList is in fact 2 (the empty delegate and the subscriber) so it checks out.
Okay. I don't know why but I figured out the solution so that other ones who stumble with the issue can find a solution. It was related with a extension I created for the Random class (which wasn't throwing a exception although... so it might be a bug on C#, I can't really explain). The Random extension is provided by an external NuGet package I created.
Version A (without using the Random Extension):
Body of the EventHandler:
LogDebug("Inside Handler");
double intensityValue2 = GetRandomNumber(Settings.MinimumIntensity, Settings.MaximumIntensity);
double frequency2 = GetRandomNumber(Settings.MinimumFrequency, Settings.MaximumFrequency);
int repetitions2 = GetRandomInt(Settings.MinimuMRepetitions, Settings.MaximumRepetitions);
Version B (using Random extension):
Body of EventHandler:
LogDebug("Inside Handler");
double intensityValue2 = random.GetRandomNumber(Settings.MinimumIntensity, Settings.MaximumIntensity);
double frequency2 = random.GetRandomNumber(Settings.MinimumFrequency, Settings.MaximumFrequency);
int repetitions2 = random.GetRandomNumber(Settings.MinimuMRepetitions, Settings.MaximumRepetitions);
Version A is the one that it is working. The Logs are guaranteed to appear. I don't know why it isn't letting me use extensions but it is solved for now. It would make sense if the Random extension threw an exception but it is not the case...
If any other person stumbles upon the issue I hope this helps you figure out the issue faster than me.
Thank you
Edit: typo

How to make event calling holder class function

This may have been asked several times, but I don't know what to search for..
Anyway. I have a class called Character. Inside of it I want to have a collision component that I have called RectangleCollision. Inside of it there is a function called IsOverlapping that checks for overlap.
I want to have a function that can be modified for each game object. For example create a function called OnBeginOverlap(); that will fire everytime the collision component detects a collision.
Is there any way that I can bind this function as delegate or event? Or something?
You have to read about events and delegates. There are plenty of examples on the web. The easiest I managed to find when I was trying to understand the subject was this:
The Simplest C# Events Example Imaginable
You can also check out the below (you can compile this as console application):
class Character
{
public delegate void OverlappingHandler(Character character, EventArgs e);
public event OverlappingHandler OverlappingEvent;
public void IsOverlapping()
{
bool overlapping = true;
if (overlapping)
{
if (OverlappingEvent != null)
{
OverlappingEvent(this, null);
}
}
}
}
class Program
{
static void Main(string[] args)
{
Character c = new Character();
c.OverlappingEvent += OverlappingEventHandler;
c.OverlappingEvent += OverlappingSecondEventHandler;
c.IsOverlapping();
Console.Read();
}
static void OverlappingEventHandler(Character character, EventArgs e)
{
Console.WriteLine("We have overlapping here!!");
}
static void OverlappingSecondEventHandler(Character character, EventArgs e)
{
Console.WriteLine("Seriously, we have overlapping !!");
}
}
So step by step:
Create a delegate, which is a bridge between your event and the code you want to run when event is triggered. You give parameters to a delegate, which are (object sender, EventArgs e) - in this example sender is the Character class, arguments are used to send additional info - for example type of character.
Create event of our delegate type
In our function IsOverlapping() there would be your logic checking if there is overlapping happening. If there is, you fire up event. You should check first if there is anything connected to the event (hence the if (OverlappingEvent != null)) - if some there is something, fire up the event.
In the Main() you create an instance of the class and...
Subscribe your event handlers to it, so the code that should be executed when the event is triggered. I connected two methods, just to show that you can subscribe more than one.
Now when you run c.IsOverlapping() this is what happens:
your logic to check overlapping runs,
if there is overlapping, there will be a check if OverlappingEvent has code subscribed (it does in Main()),
if it does event will be triggered,
code subscribed to the event runs - in this case your code in Main().
You can compile this as console app and it will display 2 lines:
We have overlapping here!!
Seriously, we have overlapping !!
Hope this helps.

C# - Static events on non-static classes

There are situations where I'm quite fond of static events, but the fact that I rarely see them in other people's code makes me wonder if I'm missing something important. I found a lot of discussions about static events on this site, but most of them deal with situations that I'm not interested in (like on static classes) or where I wouldn't think of using them in the first place.
What I am interested in are situations where I might have many instances of something and a single instance of a long-living "manager" object that reacts to something on those instances. A very simple example to illustrate what I mean:
public class God {
//the list of followers is really big and changes all the time,
//it seems like a waste of time to
//register/unregister events for each and every one...
readonly List<Believer> Believers = new List<Believer>();
God() {
//...so instead let's have a static event and listen to that
Believer.Prayed += this.Believer_Prayed;
}
void Believer_Prayed(Believer believer, string prayer) {
//whatever
}
}
public class Believer {
public static event Action<Believer, string> Prayed;
void Pray() {
if (Prayed != null) {
Prayed(this, "can i have stuff, please");
}
}
}
To me, this looks like a much cleaner and simpler solution than having an instance event and I don't have to monitor changes in the believers collection either. In cases where the Believer class can "see" the God-type class, I might sometimes use a NotifyGodOfPrayer()-method instead (which was the preferred answer in a few similar questions), but often the Believer-type class is in a "Models"-assembly where I can't or don't want to access the God class directly.
Are there any actual downsides to this approach?
Edit: Thanks to everyone who has already taken the time to answer.
My example may be bad, so I would like to clarify my question:
If I use this kind of static events in situations, where
I'm sure there will only ever be one instance of the subscriber-object
that is guaranteed to exist as long as the application is running
and the number of instances I'm watching is huge
then are there potential problems with this approach that I'm not aware of?
Unless the answer to that question is "yes", I'm not really looking for alternative implementations, though I really appreciate everyone trying to be helpful.
I'm not looking for the most pretty solution (I'd have to give that prize to my own version simply for being short and easy to read and maintain :)
One important thing to know about events is that they cause objects which are hooked to an event not to be garbage collected until event owner is garbage collected, or until event handler is unhooked.
To put it into your example, if you had a polytheistic pantheon with many gods, where you promoted and demoted gods such as
new God("Svarog");
new God("Svantevit");
new God("Perun");
gods would remain in your RAM while they are attached to Believer.Prayed. This would cause your application to leak gods.
I'll comment on design decision also, but I understand that example you made is maybe not best copy of your real scenario.
It seems more reasonable to me not to create dependency from God to Believer, and to use events. Good approach would be to create an event aggregator which would stand between believers and gods. For example:
public interface IPrayerAggregator
{
void Pray(Believer believer, string prayer);
void RegisterGod(God god);
}
// god does
prayerAggregator.RegisterGod(this);
// believer does
prayerAggregator.Pray(this, "For the victory!");
Upon Pray method being called, event aggregator calls appropriate method of God class in turn. To manage references and avoid memory leaks, you could create UnregisterGod method or hold gods in collection of weak references such as
public class Priest : IPrayerAggregator
{
private List<WeakReference> _gods;
public void Pray(Believer believer, string prayer)
{
foreach (WeakReference godRef in _gods) {
God god = godRef.Target as God;
if (god != null)
god.SomeonePrayed(believer, prayer);
else
_gods.Remove(godRef);
}
}
public void RegisterGod(God god)
{
_gods.Add(new WeakReference(god, false));
}
}
Quick tip: Temporarily store event delegate as listeners might unhook their event handlers
void Pray() {
var handler = Prayed;
if (handler != null) {
handler(this, "can i have stuff, please");
}
}
Edit
Having in mind details you added about your scenario (huge number of event invokers, constant and single event watcher) I think you chose right scenario, purely for efficiency reasons. It creates least memory and cpu overhead. I wouldn't take this approach generally, but for scenario you described static event is very pragmatic solution that I might take.
One downside I see is flow of control. If your event listener is created in single instance as you say, then I would leverage singleton (anti)pattern and invoke method of God from Believer directly.
God.Instance.Pray(this, "For the victory!");
//or
godInstance.Pray(this, "For the victory!");
Why? Because then you get more granular control over performing action of praying. If you decide down the line that you need to subclass Believer to a special kind that doesn't pray on certain days, then you would have control over this.
I actually think that having an instance even would be cleaner and defiantly more readable.
It is much more simple to view it as, an instance is preying, so his pray event gets trigger. And I don't see ant downsides for that. I don't think that monitor changes is not more of a hustle than monitoring the static event. but is the correct way to go...
Monitoring the list:
Change the list to be an ObservableCollection (and take a look at NotifyCollectionChangedEventArgs ).
Monitor it by:
public class God {
readonly ObservableCollection<Believer> Believers = new ObservableCollection<Believer>();
public God() {
Believers = new ObservableCollection<T>();
Believers.CollectionChanged += BelieversListChanged;
}
private void BelieversListChanged(object sender, NotifyCollectionChangedEventArgs args) {
if ((e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace) && e.OldItems != null)
{
foreach (var oldItem in e.OldItems)
{
var bel= (Believer)e.oldItem;
bel.Prayed -= Believer_Prayed;
}
}
if((e.Action==NotifyCollectionChangedAction.Add || e.Action==NotifyCollectionChangedAction.Replace) && e.NewItems!=null)
{
foreach(var newItem in e.NewItems)
{
foreach (var oldItem in e.OldItems)
{
var bel= (Believer)e.newItem;
bel.Prayed += Believer_Prayed;
}
}
}
}
void Believer_Prayed(Believer believer, string prayer) {
//whatever
}
}

How to run a function on a background thread for Windows Phone 7?

I'm using MVVM Light to build a WP7 (Windows Phone 7) application. I wish to have all the work performed by the Model to be run on a background thread. Then, when the work is done, raise an event so that the ViewModel can process the data.
I have already found out that I cannot invoke a Delegate asynchronously from an WP7 app.
Currently I am trying to use ThreadPool.QueueUserWorkItem() to run some code on a background thread and use MVVM Light's DispatcherHelper.CheckBeginInvodeOnUI() to raise an event on the UI thread to signal the ViewModel that the data has been loaded (this crashes VS2010 and Blend 4 when they try to display a design-time view).
Is there any sample code to run some code on a background thread and then dispatch an event back to the UI thread for a WP7 app?
Thanks in advance,
Jeff.
Edit - Here is a sample Model
public class DataModel
{
public event EventHandler<DataLoadingEventArgs> DataLoadingComplete;
public event EventHandler<DataLoadingErrorEventArgs> DataLoadingError;
List<Data> _dataCasch = new List<Data>();
public void GetData()
{
ThreadPool.QueueUserWorkItem(func =>
{
try
{
LoadData();
if (DataLoadingComplete != null)
{
//Dispatch complete event back to the UI thread
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//raise event
DataLoadingComplete(this, new DataLoadingEventArgs(_dataCasch));
});
}
}
catch (Exception ex)
{
if (DataLoadingError != null)
{
//Dispatch error event back to the UI thread
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//raise error
DataLoadingError(this, new DataLoadingErrorEventArgs(ex));
});
}
}
});
}
private void LoadData()
{
//Do work to load data....
}
}
Here's how I'd approach a solution to this.
Your ViewModel implements INotifyPropertyChanged right? There's no need to dispatch the Events. Just raise them "bare" in the Model, then dispatch the RaisePropertyChanged in the ViewModel.
And yes, you should have some sort of singleton model/database in your code. After all, what is a SQL Database if not some gigantic singleton? Since we don't have a database in WP7, don't be shy creating a singleton object. I have one called "Database" :)
I've just tried threading my dataloads in there, and realise that in fact the best approach is simply implementing INotifyPropertyChanged right down at the model level. There's no shame in this.
So given that, here's what I'm doing in the singleton Database object to load and return my Tours "table" (note the thread.sleep to make it take a visible amount of time to load, normally its sub 100ms). Database class now implements INotifyPropertyChanged, and raises events when loading is completed:
public ObservableCollection<Tour> Tours
{
get
{
if ( _tours == null )
{
_tours = new ObservableCollection<Tour>();
ThreadPool.QueueUserWorkItem(LoadTours);
}
return _tours;
}
}
private void LoadTours(object o)
{
var start = DateTime.Now;
//simlate lots of work
Thread.Sleep(5000);
_tours = IsoStore.Deserialize<ObservableCollection<Tour>>( ToursFilename ) ?? new ObservableCollection<Tour>();
Debug.WriteLine( "Deserialize time: " + DateTime.Now.Subtract( start ).ToString() );
RaisePropertyChanged("Tours");
}
You follow? I'm deserializing the Tour list on a background thread, then raising a propertychanged event.
Now in the ViewModel, I want a list of TourViewModels to bind to, which I select with a linq query once I see that the Tours table has changed. It's probably a bit cheap to listen for the Database event in the ViewModel - it might be "nicer" to encapsulate that in the model, but let's not make work we we don't need to eh?
Hook the Database event in the Viewmodel's constructor:
public TourViewModel()
{
Database.Instance.PropertyChanged += DatabasePropertyChanged;
}
Listen for the appropriate table change (we love magic strings! ;-) ):
private void DatabasePropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "Tours")
{
LoadTourList();
}
}
Select the records I want from the table, then tell the view there is new data:
public void LoadTourList()
{
AllTours = ( from t in Database.Instance.Tours
select new TourViewModel( t ) ).ToList();
RaisePropertyChanged( "AllTours" );
}
And lastly, in your ViewModelBase, it's best to check if your RaisePropertyChanged needs dispatching. My "SafeDispatch" method is pretty much the same as the one from MVVMlight:
private void RaisePropertyChanged(string property)
{
if ( PropertyChanged != null )
{
UiHelper.SafeDispatch(() =>
PropertyChanged(this, new PropertyChangedEventArgs(property)));
}
}
This works perfectly in my code, and I think is fairly tidy?
Lastly, extra for experts: in WP7, it might be good to add a ProgressBar with IsIndeterminate=True to your page - this will display the "dotted" progress bar. Then what you can do is when the ViewModel first loads you could set a "ProgressBarVisible" property to Visible (and raise the associated PropertyChanged event). Bind the ProgressBar's visibility to this ViewModel property. When the Database PropertyChanged event fires, set the visibility to Collapsed to make the progressbar go away.
This way the user will see the "IsIndeterminate" progress bar at the top of their screen while the deserialization is running. Nice!
I have not developed for WP7 before, but I found this article that might be useful!
Here is the Dining Philosopher sample code from the article that should give you a good idea on how to raise an event to the UI from another thread:
public DinnersViewModel(IDinnerCatalog catalog)
{
theCatalog = catalog;
theCatalog.DinnerLoadingComplete +=
new EventHandler<DinnerLoadingEventArgs>(
Dinners_DinnerLoadingComplete);
}
public void LoadDinners()
{
theCatalog.GetDinners();
}
void Dinners_DinnerLoadingComplete(
object sender, DinnerLoadingEventArgs e)
{
// Fire Event on UI Thread
View.Dispatcher.BeginInvoke(() =>
{
// Clear the list
theDinners.Clear();
// Add the new Dinners
foreach (Dinner d in e.Results)
theDinners.Add(d);
if (LoadComplete != null)
LoadComplete(this, null);
});
}
I hope it's helpful :).
One thing that's confusing: you said that when you use the helper to raise the event, then VS2010 crashes... what exactly are you seeing when it's crashing? Are you getting an exception?
Jeff, I'm still figuring this stuff out myself. I posted a similar question and ended up answering it myself by building a simple sample. Here:
A super-simple MVVM-Light WP7 sample?
The summary is:
1) I derived my Model (yes my model) from ViewModelBase. This gives me Mvvm-Light's implementation of messaging and INotifyPropertyChanged which is handy. You could argue this is not "pure" but I don't think it matters.
2) I used Mvvm-Light DispatcherHelper.CheckBeginInvokeOnUIhelper just as you did (from my Model, NOT my ViewModel).
Hope this helps.

Categories

Resources