Order of Precedence with methods? - c#

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!

Related

Can I use Invoke instead of BeginInvoke to address suspension of Dispatcher processing?

One of our clients has reported an issue with one of our Add-ins becoming unresponsive. The error reported contains a stack trace that goes deep into the bowels of WPF and I won't distract you with that. Suffice to say that the top level error reads:
Dispatcher processing has been suspended, but messages are still being processed.
The same code works perfectly on my, and as far as I know any other, machine. All the code does is instantiate a WPF window and call its .ShowDialog() method.
Looking through issues with the same error, I find answers such as this:
Dispatcher throws InvalidOperationException on Messagebox.Show in Textchanged event
or
WPF : Dispatcher processing has been suspended, but messages are still being processed
In both cases the answer provided is to use Dispatcher.BeginInvoke
The problem with that is that this call is asynchronous and I need to wait for user response. So I use Dispatcher.Invoke instead:
Dispatcher.Invoke(Sub() oAIC.ShowDialog(), System.Windows.Threading.DispatcherPriority.Normal)
Once again this works perfectly on my machine but that means nothing. The original code worked perfectly on my machine, too.
So my question is:
Is this even worth pursuing? Or is the fact that I use .Invoke instead of .BeginInvoke equivalent to me just using the original .ShowDialog() directly so I'm wasting my time?
Suffice to say that the client in question is not of the cooperative kind. Other clients would be happy for me to give them a trial version and report back, but this person simply wants a solution and doesn't want to be bothered with anything else. As this has never been reported by any other client I can't even find another "guinea pig" to try this on, so all I have left is the option to ask it here in the hope that someone with sufficient expertise can tell me "yes this is a good way forward" or "you're wasting your time". Sorry if this doesn't quite fit the model for asking questions here but I'm at the end of my rope...
further clarification after seeing Peregrine's answer
The code is part of an Office Add-in (in this case for Microsoft Word). The WPF dialog I'm trying to display pops up several levels down from a button click in the Ribbon Bar.
I put the code behind the button click into a function
DoTheButtonCode()
and called it as follows
Await System.Threading.Tasks.Task.Run(AddressOf DoTheButtonCode)
When I tried this, an error was raised:
An exception of type 'System.InvalidOperationException' occurred in PresentationCore.dll but was not handled in user code
Additional information: The calling thread must be STA, because many UI components require this.
Now this is the weird thing. In the original Button Click event, the apartmentstate of system.threading.thread.currentthread is STA but when I then step into the DoTheButtonCode and I check system.threading.thread.currentthread its apartmentstate is MTA
further clarification
Ok - tried something else:
Changed DoTheButtonCode to an Async Function:
Private Async Function DoTheButtonCode() As Threading.Tasks.Task(Of Integer)
The button Click event handler method is now defined Private Async Sub, and within it I call
Await DoTheButtonCode()
This actually works, apart from this niggling warning that appears in the function definition of DoTheButtonCode: "this async method lacks 'Await' operators and so will run synchronously" (etc)
So while this does work I suspect that I'm kidding myself here.
I think I'm about ready to give up. I'll just add a try/catch construct around my original ShowDialog call and if the error is raised at least it will simply do nothing rather than crash :(
Thanks for all your help, Peregrine
I'm doing something very similar in my library for displaying message dialogs in a MVVM pure manner.
The only differences I can see between my code and yours is
I'm using Dispatcher.InvokeAsync() rather than Dispatcher.Invoke() - which makes the call awaitable.
I'm creating my dialog window inside the Dispatcher.BeginInvoke() call - it's not clear where your oAIC window is being created.
private async Task<perDialogButton> _ShowDialogAsync(object viewModel, object content, string title, perDialogButton buttons, perDialogIcon dialogIcon)
{
// get control associated with ViewModel instance
var associatedControl = ...
return await associatedControl.Dispatcher.InvokeAsync(() =>
{
var window = new perDialog
{
// set dialog properties
...
};
window.ShowDialog();
return window.SelectedButton;
});
}
Mode details, and the full source code on my blog post

How to run events sequentially in C# or Similar Frameworks

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

Threading in C# with XNA KeyboadInput

I am a bit new to threading (not new to C#, just haven't done much threading). Can someone explain to me why this does not work?
I have a thread which calls a method I will call "Loop". Loop contains a while loop which will continuously run, and on every loop of the while I want it to check if the A Key is down (using Microsoft's Keyboard class within the XNA Framework). But for some reason it never registers that anything is being pressed.
static Thread thread = new Thread(Loop);
static bool abort = false;
public static void Begin()
{
thread.Start();
}
private static void Loop()
{
while (!abort)
{
if (Keyboard.GetState().IsKeyDown(Keys.A))
Console.WriteLine("A pressed.");
}
}
Might anyone know why the Console.WriteLine() is never being called?
EDIT:
I guess I should explain a little bit. What I am actually trying to do is create something similar to ActionScript's events in C#. So I want to pass a "condition" and an "action" to call if that condition is met in this separate class which contains this thread. What this would do would allow me to just add "event listeners" to objects and it would automatically constantly check if one of the events gets triggered, rather than leave it to me to write If statements in code to check for the events.
Upon trying to do so, the first thing I tested was regarding this XNA Keyboard stuff, because it was one of the reasons I originally wanted to build this system, but it didn't work. So I created the standalone code which i posted above to see if I had made an error in my previous code and it still didn't work.
I never use XNA so I didn't really "know" but I've run into similar situations where you can't get keyboard (and other) input from a worker thread. I googled and found that in XNA this does seem to be the case. See this for example
So you need to (and probably want to) process your game input in the GUI thread. Just checking for input on each update tick should be fine. I doubt even if it did work, you would gain any performance - and you might introduce some interesting synchronization bugs ;-)
It does look like your creating your worker thread properly - this just isn't an application for it.

Can I Trust LoadOperation.Completed event

Suppose that we have the code shown below,
LoadOperation lop=_dsrvX.Load(_dsrvX.GetUserDetails(userID));
lop.Completed +=(s,a)=>
{
Debug.WriteLine("Completed but,
First I load it then I registered Completed evet!");
}
I see this type code everywhere so I wonder is it right?
As I know when you call domainService methods this automatically fills domain service object's related EntitySet.
Suppose that LoadOperation(Can be Submit,Invoke ops.) completed rapidly and when I passed to the next line where I register completed event everything has done.Is it possible? It seems hard to achive that but can you give me 100% guarantee?
If you can't guarantee that I'm asking if there is a method of calling OperationBase objects manually?
Any comment will be appreciated.
Well, this is a crazy world, I would not give 100% guarantee of anything :P - But I do not think it should be a problem. If this bothers you, you can pass the callback as a parameter, like this:
_dsrvX.Load(_dsrvX.GetUserDetails(userID), userDetailsCallBack, null);
(...)
void userDetailsCallBack(LoadOperation<UserDetails> op)
{
//do anything with the results
}
or, to simplify even further:
_dsrvX.Load(_dsrvX.GetUserDetails(userID), (op)=>
{
//do anything with the results
}, null);
Yes you can trust it - 100% guaranteed!
If you dig into the code behind the asynchronous Load method, you will see that it starts up another thread, to do the actual load, then returns immediately.
That separate thread then prepares for a service call, performs the service call, and eventually returns the resulting data.
It cannot trigger the Completed event until that is all done and we are talking "a lot" of code to get through, not to mention waiting on a web-service, whereas the return is pretty much instantaneous after the thread was started. i.e. no chance for the other thread to complete and interrupt it.
There is 0% chance that the load will complete before you add the handler on the next line.
The usual approach is to provide a callback or anonymous method instead, but your existing code is fine. MS knew what they were doing when the designed it that way :)
I had this argument with Jon Skeet, on a related question, and his reaction was that you don't know what the Load method is doing so it "might" happen faster than the return... My pragmatic answer was that we know exactly what is going on, by design, and it 100% returns before the Load even commences

C# detect if calls were in the same UI action

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...

Categories