How to Cancel/Regulate event which is executing in parallel with same event in another thread.
For e.g. In a textbox, every time we enter a character the event fires if text changed event is defined. But after entering first character, the event (Let us call First Event) takes lot of time (as there will be more strings which match a single character), and does some action like changing content of a title label. And after entering a second character the new event which raised to run in parallel takes less time. So now, the second event which fired after entering second character executes fast and returns first and first event executes last and thus, first event's result will be printed ultimately on the label rather than the second one.
Is there a better way to cancel the first event before starting the second event. One thing that comes to my mind is to register threads on a global list variable and kill all threads which are not dead before starting your execution. Will this work?? Any better way to handle this situation.
P.S. I know that search could be initiated after a space or enter to solve this particular issue. But I think you have already noticed my main point. :)
My favourite library for dealing with this exact problem is Rx.Net with TPL. This behaviour can be easily implemented with a combination of a Cancellable Task with an event observer using Observable.FromAsync
Some code!
var textChanged = Observable.FromEventPattern(x => textBox.TextChanged += x, x => textBox.TextChanged -= x)
.Select(_ => textBox.Text);
IDisposable eventHandler = textChanged.Throttle(TimeSpan.FromMilliseconds(500))
.Select(text => Observable.FromAsync((TaskCancelationToken cancel) => DoSearchTaskAsync(text, cancel)))
.Switch()
.Subscrible(results =>
{
//Update the UI
});
Note there is no need to explicitly type any of this...I am only doing it for clarity, but I am more than likely to have mistyped a class name or two...
EDIT
The Search method would be the method body of Task<TReturn> DoSearchTaskAsync(string, TaskCancellationToken).
The magic sauce comes from the Observable.FromAsync and Observable.Switch.
Each time we have a change in the textBox.Text we fire an event. That is filtered by the .Throttle (as you would expect). The clever bit is when we then create a new event source on DoSearchTaskAsync using Observable.FromAsync. At this point we have an IObservable<IObservable<TResult>>, or another way to put it, an eventsource of an eventsource. The switch means we only want the results from the most recently sent eventsource from the outter eventsource, and kill (Dispose) the subscription of previous eventsources.
The act of disposing the previous Observable.FromAsync will cause the TaskCancellationToken to cancel, and prevent its results bubbling up, whilst we subscribe to the new Task.
All very clever stuff, and I only recently came across this AWESOME pattern (I would credit the author if I could).
As for the Observable.FromEventPattern that is pretty unfortunate, as of C#5, there are no first class eventhandlers, so we pass in a lambda for subscription and a lambda for de-subscription.
The .NET Task API has the concept of cancellation built in. See this page for an example and links to more information. http://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx
Related
How do I setup an event loop (main loop) in a UWP app?
My goal is to have an app that has a main page with a continuously updating calculation, that then continuously updates an image on the page. While that is constantly happening, the user can click a button to change the calculation behavior, or to go to a second page and edit related data.
The user can then click back to the main page and see the image and calculation restart and continuously update. (The calculation is complex, so it should go as fast as possible and use up as much app time as possible).
If there is a way to accomplish this without an event loop I would like to know that also, but so far I have not found a way.
With an event loop, I can simply update the calculation and UI every time through the loop. But I have not found any way to do so. This question asked nearly the same thing, but was never directly answered and had a different use case anyway.
The closest I have found to a solution is to grab the CoreDispatcher from the CoreWindow and use the RunIdleAsync() method to create a loop:
public MainPage()
{
this.InitializeComponent();
Windows.UI.Core.CoreWindow appwindow = Windows.UI.Core.CoreWindow.GetForCurrentThread();
Windows.UI.Core.CoreDispatcher appdispatcher = appwindow.Dispatcher;
//create a continuously running idle task (the app loop)
appdispatcher.RunIdleAsync( (dummyt) =>
{
//do the event loop here
.
.
.
if (appdispatcher.ShouldYield()) //necessary to prevent blocking UI
{
appdispatcher.ProcessEvents(Windows.UI.Core.CoreProcessEventsOption.ProcessAllIfPresent);
}
});
}
The main problem with this is that you can't switch between pages (you get a system exception from dispatching events within an already dispatched event).
Second, this is very messy and requires maintaining extra state in the event loop. Besides, why should I have to go through these contortions just to have some calculations happening while the app is waiting for user input?
Is there a way to do this (besides switching to a C++ DirectX app)?
I don't know about setting up your own event loop, but there is no reason to do so.
What you are talking about sounds like a great case for Tasks. You would start a calculation Task whenever your user did something, having it report its progress via standard C# events if you need mid-operation updates. Those updates would modify properties in your view model which the binding system would then pick up.
You could also make your calculation code cancellable so changes can abort a previous calculation.
All of this involves pretty standard UWP concepts; no need for a special event loop. That you are even considering that makes me think you need to study MVVM and multi-threading/tasks; you are still thinking in a very "Win-Forms" kind of way.
If we're talking about some event loop, or stream, .Net has a great library named Rx, or Reactive Extensions, which may be helpful for you. You can set up a simple flow, something like this:
var source = Observable
// fire event every second
.Interval(TimeSpan.FromSeconds(1), Scheduler.DispatcherScheduler)
// add timestamp for event
.Timestamp()
// gather system information to calculate
.Select(GetSystemInfo);
Note that the events right now are on UI thread, as you need to access the controls. Now you have two options: use Rx for background processing too or use TPL Dataflow' TransformBlock for processing your system information into new image (it can be Observer and Observable at a time). After that you need to get back to UI thread.
First option:
var source = Observable
// fire event every second
.Interval(TimeSpan.FromSeconds(1), DispatcherScheduler.Current)
// add timestamp for event
.Timestamp()
// gather system information to calculate
.Select(GetSystemInfo)
// expensive calculations are done in background
.Select(x => x.ObserveOn(DefaultScheduler.Instance))
.Select(x => Expensive(x))
.Select(x => x.ObserveOn(DispatcherScheduler.Current))
.Select(x => UpdateUI(x));
You probably should split this chain into several observers and observables, still the idea is the same, more information here: Rx Design Guidelines.
Second option:
var action = new TransformBlock<SystemInfo, ImageDelta>(CalculateDelta,
new ExecutionDataflowBlockOptions
{
// we can start as many item processing as processor count
MaxDegreeOfParallelism = Environment.ProcessorCount,
});
IDisposable subscription = source.Subscribe(action.AsObserver());
var uiObserver = action.AsObservable()
.Select(x => x.ObserveOn(DispatcherScheduler.Current))
.Select(x => UpdateUI(x));
I want to note that UWP and MVVM pattern do provide a possibility to work with binding between UI and ObservableCollection, which will help you to notify user in most natural way.
There are basically two patterns in avoiding duplicated registering of event handlers:
(According to this discussion: C# pattern to prevent an event handler hooked twice)
Using System.Linq namespace, and check if the event handler is registered by calling GetInvocationList().Contains(MyEventHandlerMethod);
Do the unregistering before registering, like this:
MyEvent -= MyEventHandlerMethod;
MyEvent += MyEventHandlerMethod;
My question is, performance-wise, which one is better, or is there a significant difference between them in performance?
I don't think this matters a lot, both in assumed performance gain and actual difference.
Both GetInvocationList and -= walk the internal array _invocationList. (See source)
The LINQ extension method Contains will take more time since it needs the entire array to be walked and converted, returned and then checked by Contains itself. The Contains has the advantage it doesn't need to add the event handler if it exists which will mean some performance gain.
won't work for external callers, and is not very efficient anyway
should be fine (note that it creates 2 delegate instances each time, though), however also consider
in most scenarios, it should be easy to know whether you are already subscribed; if you can't know, then that suggests an architectural problem
The typical usage would be "subscribe {some usage} [unsubscribe]" where the unsubscribe may not be necessary, depending on the relative lifetimes of the event publisher and subscriber; if you actually have a re-entrant scenario, then "subscribe if not already subscribed" is itself problematic, because when unsubscribing later, you don't know if you're preventing an outer iteration receiving the event.
According the documentation, invocation list is being stored as array or something similar to it, and the order of the event handlers is being stored too. May be there are inner structure to maintain fast search for a particular method there.
So in the worst case operation of the GetInvocationList().Contains(MyEventHandlerMethod); is O(1) (as we simply got the reference for the array) + O(n) for searching the method, even if there is no optimization for it. I seriously doubt that this is true, and I think that there is some optimizing code, and it is O(log_n).
Second approach has additional operation of adding which is, I think, O(1), as we adding the event handler to the end.
So, to see the difference between such actions, you need a lot of the event handlers.
But! If you use the second approach, as I said, you'll add the event handler to the end of the queue, which can be wrong in some cases. So use the first one, and has no doubt in it.
MyEvent -= MyEventHandlerMethodfirst need to find the registered event handler in the invocation list in order to remove it.
So GetInvocationList().Contains is better, but it's truely insignificant.
But, notice that you can't access event EventHandler foo's invocation list....
I have a simple Windows Phone 8 app with a button and a textbox. How do I use Reactive Extensions for the button Tap and Hold event to change the TextBox text?
void AttachRx()
{
IScheduler cs = new DispatcherScheduler(Deployment.Current.Dispatcher);
Observable.FromEvent<System.Windows.Input.KeyEventArgs>(btn, "Tap").Throttle(TimeSpan.FromSeconds(.5), cs)
.Do(a => ChangeText()).Subscribe();
}
error message:
{System.InvalidOperationException: The event delegate must be of the form void Handler(object, T) where T : EventArgs.
at Microsoft.Phone.Reactive.Observable.FromEvent[TEventArgs](Object target, String eventName)
at PhoneApp4.MainPage.AttachRx()
at PhoneApp4.MainPage..ctor()}
There are a few issues to address here.
The error you've reported is specifically saying that the delegate you are trying to add to the Tap event is not compatible - which makes sense because I don't imagine the Tap event has a KeyEventArgs payload (I think it is GestureEventArgs)? You are also probably better off using Observable.FromEventPattern as used in my example below. It's easier as you can get away with inferring the EventArgs type.
Caveat - As I have only WP8.1 SDK on my laptop at the moment, I have only the Win RT Tapped Event which is different from Tap, so I've just read the docs on Tap and not run the example below.
Assuming a Button called btn and a TextBox called txt and a function string GetText() that gets the text to set, do this:
Observable.FromEventPattern<GestureEventArgs>(btn, "Tap")
.Throttle(TimeSpan.FromSeconds(0.5))
.Select(_ => GetText())
.ObserveOnDispatcher()
.Subscribe(x => this.txt.Text = x);
Note a few things here:
Use FromEventPattern when standard .NET events are available - it better suited for this than FromEvent which really exists to handle non-conforming delegates.
Don't use Do like this. It works as a side-effect and isn't really idiomatic functional reactive programming. Doing this is in general could also cause unintended problems in more complex queries. Instead, project the input event to the desired result with a Select.
Don't run the Throttle on the dispatcher - use the default scheduler (or parameterize for testability with .Throttle(TimeSpan.FromSeconds(0.5), Scheduler.Default). You don't need the Throttle to run on the dispatcher - it's better off in the background. You only want to transfer to the dispatcher when you are ready to update the UI.
If you import nuget package rx-xaml you can use ObservableOnDispatcher to grab the current dispatcher. Although, for testability, you may wish to use the overload of ObserveOn (also in rx-xaml) that takes a dependency object like the page you are running on - e.g. ObserveOn(this) if you set up the subscription in the page code-behind for example, the page itself will do.
The example above assumes that GetText is synchronous. If you need to make an asynchronous call to get the text you wish to display, use the following pattern (assuming that GetText has a Task<String> return type):
Observable.FromEventPattern<GestureEventArgs>(btn, "Tap")
.Throttle(TimeSpan.FromSeconds(0.5), Scheduler.Default)
.Select(_ => Observable.FromAsync(GetText)
.ObserveOn(this))
.Switch()
.Subscribe(x => this.Name.Text = x);
Note the strange looking placement of ObserveOn inside the Select. The reasons for this are quite complex to explain briefly (and I'm not sure how relevant it is to this question), but basically it avoids a race condition where if a long running async GetText call for an earlier event could over-write the results of a short running call due to a later event.
I have some nice, working edit-undo functionality in my winforms application. It works using a CommandStack class, which is two Stack<IStateCommand>s (one for undo, one for redo). Each command has an Execute and an Undo method, and the CommandStack object itself has an event that is fired when the stacks are changed.
The CommandStack also works out if the LogCommand method is called from its own Undo function, and therefore adding it to the redo stack, rather than the undo stack. This is done by simply adding the current ManagingThreadId to a List<int> object, then removing it after the Undo command is completed (as opposed to using the stack trace, which I believe would be much slower and a bit dirty).
There is a lot of different commands within my application so this formula is sort of set in stone as it'll take me a few days to redo all those IStateCommands implementations.
The only problem with this, currently, some UI events within also call other UI events, both of which log an IStateCommand to the undo history. Is there any way in C# that I can detect if the LogCommand function has already been called from the same UI event (Click, DragDrop, SelectedIndexChanged, TextChanged, etc), then I can combine the commands into one command (using my CommandList class, which also inherits IStateCommand)?
I've thought of saving the current time when the undo event was called, then if the next command is logged less than x milliseconds later, combine them in the history, but this seems a bit sloppy. I've also considered searching the stack trace, but I don't really know what to look for to find the root UI event, nor do I know whether I would tell the different between one button click, then a different click on the same button.
It may also be helpful to know that all of these commands are being called from the UI thread from event handlers (mostly from events from custom user controls). The only part of my application that uses another thread runs after most UI events, after the undo history is logged.
Thanks!
Sort Version
The same method is being called twice from the same UI event (eg, MouseUp, DragDrop). The second time this method is called, how do I check that it has already been called once by the same UI event?
Edit: The solution (sort of)
It's a bit of a dirty one as I don't have the time to completely re-write this system. However I've implemented it in such a way that gives the option not to be so dirty in the future.
The solution is based on one of Erno's comments on his answer (so I will mark his answer as accepted), where he suggests added a parameter. I added another overload to my LogCommand(IStackCommand) method in the CommandStack class, LogCommand(IStackCommand, string). The string is the actionId, which is stored for each command, and if this string is the same as the last, the commands are combined. This gives the option to go through each event and give a unique ID.
However, the dirty part - to get it working before we have to show the client, the actionId defaults to System.Windows.Forms.Cursor.Position.ToString(), ouch!! Since the cursor position is not changed while the UI thread is executing, this combines each command. It actually even combines TextChanged commands (as long as they don't move their mouse!)
It might be an option to add a local stack of called-commands to a command.
When a command executes other commands add the command to the local stack so you can undo the commands on this local stack when the command must be undone or redone.
EDIT
I am not quite sure what you don't understand.
I would simply add a CommandList property to the StateCommand. Everytime the StateCommand invokes/triggers another StateCommand it should add the new StateCommand to the CommandList. So the global CommandList keeps track of the Commands that can be undone from the UI and each StateCommand keeps track of the StateCommands it invoked (so these are not added to the global undo CommandList)
EDIT 2
If you can't or do not want to change to that setup you would have to pass a parameter to the execution of the commands that links them together.
Did you try to inspect the method stack and analyze it method-by-method:
StackTrace st = new StackTrace();
for ( int i=0; i<st.FrameCount; i++ )
{
StackFrame sf = st.GetFrame(i);
MethodBase mb = sf.GetMethod();
// do whatever you want
}
I don't know what you need exactly to achieve, but I implemented something similar, maybe you can get some ideas...
In summary, you can store some information in a ThreadStatic variable. Then, any time you want to log a command, inspect the thread static variable to find out the context in which you are logging the command. If it's empty, you are starting a new command logging sequence. If not, you are inside a sequence.
Maybe you can store the entry event (e.g. Click, DragDrop,...), or the command itself... It depends on your needs.
When the initial event callback is completed, clean the static variable to signal that the sequence has been completed.
I successfully implemented a similar strategy to track commands executed upon an object model. I encapsulated the logic within an IDisposable class that also implemented the reference counting to handle the nested usings. The first using started the sequence, subsequents using statements increased and decreased the reference counting to know when the sequence was completed. The outermost context disposing fired an event containing all the nested commands. In my specific case it has worked perfectly, I don't know if it may fulfill your needs...
Say I have 2 methods. One is an method triggered by the selected index changing in the listbox. The second method helps by clearing all textboxes, setting listbox index to -1, and setting the focus.
Question:
Method two executes, during the code it changes the selected index of the listbox to -1, thereby setting off the event trigger for the 1st method. Does Method 2 HALT it's own execution and transfer the process to the event, and then return back to its work after Method 1 is finished... OR does method 2 finish its entire codeblock then transfer to Method 1 since the selected index changes?
The first case.
Let's leave threads out of it for a moment, particularly because they're not involved in your scenario.
You're talking about properties and methods, but underneath it all, it's all just functions. When one function invokes another, control in your program transfers to the called function. When that function finishes running, control returns to the point where it was called. Your program automatically remembers where it needs to go back to, no matter how deeply functions call more functions.*
When your second function sets the index, what really happens is that the compiler translates the property-set operation into a function call. (Properties are ultimately just "syntactic sugar" for functions.) That function calls a bunch of other functions that aren't important to the scenario, except that one of them is the one that invokes the "index changed" event handler. It sees that you have a method associated with that event, and it calls your first method.
Your first method runs, and when it finishes, it returns to the "invoke the index-changed event handler" function. Eventually, that and all the other unimportant functions finish running (perhaps after making more function calls in sequence), and the "set the index property" function returns control to your second method.
You can prove to yourself that your first suggestion is how it works. Display a message box in your first method, and display another message box after the point in your second method where you set the index property. (Use different messages!) You should see the first message appear, and after you dismiss the message box, you should see the second message appear, thus showing that the second method did not continue executing while the first one was running.
* There is a limit, but it's rarely hit unless there's a bug in your program. When you have too many nested function calls, what happens is a stack overflow.
There's a third alternative you can explore: they can also run at the same time! If I understand your question correctly, method 2 would be triggered by the index change event. In a C# Windows Forms application, this other event would occur in a separate thread of execution.
Concepts to explore: threading.
I hope this gives you a starting point in your explorations of knowledge.
Assuming no multi-thread situation, the event will fire before he end of execution of the method. If you want to see this, code what you have suggested in a .NET language and examine the Il produced. You can do this with ILDASM, or Reflector, or even create your own relfletion application. You do have to understand the syntax of IL enough to see the branch, but it is not that difficult, as long as you understand programming concepts.
Rob has labeled this "syntactical sugar", which I will agree with somewhat. It is really a compiler trick, but I guess it falls under the label "syntactical sugar" as it is commonly used.
I assume the language in question is c# and you thus have a language that supports multiple threads. If you don't want to worry about threads (which would be a bad idea if you consider user experience) you can run your GUI in one thread and have the same behavior, unless the components create their own thread (which would be a bit weird though). If you want to achieve an asynchronous (parallel) execution of the event you need to have the the event triggering in its own thread.
To answer your question: if you aren't using multiple threads, the method triggered by the event will be queued. This is exactly what happens when you see GUI responding slowly in some programs.
Hope it cleared things out and welcome from another newcomer :)
I myself am a beginner, maybe I can help. Method2 would fire, then when the selection changes, Method1 would do his stuff, then Method2 would continue.
If you don't want Method1 to fire at that time, you might want to do is something like:
(REALLY pseudo code)
Method2(object sender, System.EventArgs e)
{
//Unsubscribe Method1 from ListboxEvent
Listbox.OnSelectionChange -= Method1;
... Stuff Method2 actually does ...
Manualy call Method1 if you want it to fire
//Subscribe Method1 from ListboxEvent
Listbox.OnSelectionChange += Method1;
}
It's probably not optimal (and maybe some Best Practices...) but for a lack of a better explanation, at least you have a bit of information to help you search. Hope it helps!