Can I Trust LoadOperation.Completed event - c#

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

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

When does a param that is passed by reference get updated?

Suppose I have a method like this:
public void MyCoolMethod(ref bool scannerEnabled)
{
try
{
CallDangerousMethod();
}
catch (FormatException exp)
{
try
{
//Disable scanner before validation.
scannerEnabled = false;
if (exp.Message == "FormatException")
{
MessageBox.Show(exp.Message);
}
}
finally
{
//Enable scanner after validation.
scannerEnabled = true;
}
}
And it is used like this:
MyCoolMethod(ref MyScannerEnabledVar);
The scanner can fire at any time on a separate thread. The idea is to not let it if we are handling an exception.
The question I have is, does the call to MyCoolMethod update MyScannerEnabledVar when scannerEnabled is set or does it update it when the method exits?
Note: I did not write this code, I am just trying to refactor it safely.
You can think of a ref as making an alias to a variable. It's not that the variable you pass is "passed by reference", it's that the parameter and the argument are the same variable, just with two different names. So updating one immediately updates the other, because there aren't actually two things here in the first place.
As SLaks notes, there are situations in VB that use copy-in-copy-out semantics. There are also, if I recall correctly, rare and obscure situations in which expression trees may be compiled into code that does copy-in-copy-out, but I do not recall the details.
If this code is intended to update the variable for reading on another thread, the fact that the variable is "immediately" updated is misleading. Remember, on multiple threads, reads and writes can be observed to move forwards and backwards in time with respect to each other if the reads and writes are not volatile. If the intention is to use the variable as a cross-thread communications mechanism them use an object actually designed for that purpose which is safe for that purpose. Use some sort of wait handle or mutex or whatever.
It gets updated live, as it is assigned inside the method.
When you pass a parameter by reference, the runtime passes (an equivalent to) a pointer to the field or variable that you referenced. When the method assigns to the parameter, it assigns directly to whatever the reference is pointing to.
Note, by the way, that this is not always true in VB.
Yes, it will be set when the variable is set within the method. Perhaps it would be best to return true or false whether the scanner is enabled rather than pass it in as a ref arg
The situation calls for more than a simple refactor. The code you posted will be subject to race conditions. The easy solution is to lock the unsafe method, thereby forcing threads to hop in line. The way it is, there's bound to be some bug(s) in the application due to this code, but its impossible to say what exactly they are without knowing a lot more about your requirements and implementation. I recommend you proceed with caution, a mutex/lock is an easy fix, but may have a great impact on performance. If this is a concern for you, then you all should review a better thread safe solution.

CRUD operations; do you notify whether the insert,update etc. went well?

I have a simple question for you (i hope) :)
I have pretty much always used void as a "return" type when doing CRUD operations on data.
Eg. Consider this code:
public void Insert(IAuctionItem item) {
if (item == null) {
AuctionLogger.LogException(new ArgumentNullException("item is null"));
}
_dataStore.DataContext.AuctionItems.InsertOnSubmit((AuctionItem)item);
_dataStore.DataContext.SubmitChanges();
}
and then considen this code:
public bool Insert(IAuctionItem item) {
if (item == null) {
AuctionLogger.LogException(new ArgumentNullException("item is null"));
}
_dataStore.DataContext.AuctionItems.InsertOnSubmit((AuctionItem)item);
_dataStore.DataContext.SubmitChanges();
return true;
}
It actually just comes down to whether you should notify that something was inserted (and went well) or not ?
I typically go with the first option there.
Given your code, if something goes wrong with the insert there will be an Exception thrown.
Since you have no try/catch block around the Data Access code, the calling code will have to handle that Exception...thus it will know both if and why it failed. If you just returned true/false, the calling code will have no idea why there was a failure (it may or may not care).
I think it would make more sense if in the case where "item == null" that you returned "false". That would indicate that it was a case that you expect to happen not infrequently, and that therefore you don't want it to raise an exception but the calling code could handle the "false" return value.
As it standards, you'll return "true" or there'll be an exception - that doesn't really help you much.
Don't fight the framework you happen to be in. If you are writing C code, where return values are the most common mechanism for communicating errors (for lack of a better built in construct), then use that.
.NET base class libraries use Exceptions to communicate errors and their absence means everything is okay. Because almost all code uses the BCL, much of it will be written to expect exceptions, except when it gets to a library written as if C# was C with no support for Exceptions, each invocation will need to be wrapped in a if(!myObject.DoSomething){ System.Writeline("Damn");} block.
For the next developer to use your code (which could be you after a few years when you've forgotten how you originally did it), it will be a pain to start writing all the calling code to take advantage of having error conditions passed as return values, as changes to values in an output parameter, as custom events, as callbacks, as messages to queue or any of the other imaginable ways to communicate failure or lack thereof.
I think it depends. Imaging that your user want to add a new post onto a forum. And the adding fail by some reason, then if you don't tell the user, they will never know that something wrong. The best way is to throw another exception with a nice message for them
And if it does not relate to the user, and you already logged it out to database log, you shouldn't care about return or not any more
I think it is a good idea to notify the user if the operation went well or not. Regardless how much you test your code and try to think out of the box, it is most likely that during its existence the software will encounter a problem you did not cater for, thus making it behave incorrectly. The use of notifications, to my opinion, allow the user to take action, a sort of Plan B if you like when the program fails. This action can either be a simple work around or else, inform people from the IT department so that they can fix it.
I'd rather click that extra "OK" button than learn that something went wrong when it is too late.
You should stick with void, if you need more data - use variables for it, as either you'll need specific data (And it can be more than one number/string) and an excpetion mechanism is a good solution for handling errors.
so.. if you want to know how many rows affected, if a sp returned something ect... - a return type will limit you..

Order of Precedence with methods?

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!

GC.Collect in a loop?

I found this piece of code inside System.Web.ISAPIRuntime using Reflector
public void DoGCCollect()
{
for (int i = 10; i > 0; i--)
{
GC.Collect();
}
}
Can anyone comment on this? Is there a reason to do GC.Collect() in a loop? Why 10 times and not 3, 5 or 20? Analysis indicated that it's not used inside .net framework but it's public so I suppose that IIS could call it...
edit :
Just for clarification purposes : I have never called GC.Collect and I have no intentions of using it. I know it's a bad idea in most (if not all) cases. The question is why .net framework does it. Thanks for all your answers.
Yes, that's horrible. Firstly, you shouldn't need to do it at all. However, if you really want to force garbage collection as hard as you can, and wait for it to finish, you should probably use:
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// Collect anything that's just been finalized
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
Really not a nice idea though.
Looks truly horrible :)
I don't think you're going to get a better explanation that "one of Microsoft's programmers is pretty clueless, and apparently, no one else bothered to look at his code before it was checked in". ;)
It does look scary though.
It's a fairly common response to bugs you don't understand though. For whatever reason, you're trying to call the GC, and somehow, calling it doesn't seem to solve your problem (perhaps the real problem was just that you should wait for the finalizer thread or something), so the naive solution is obviously "Well, I'll just keep calling it then".
Similar to pressing 'print' repeatedly until your document is printed.
Perhaps you should submit it to thedailywtf.com though.
Shouldn't things like this be pointed out to Microsoft? Would it do any good to post this on the Connect site?
I really like the Mono implementation of this method:
public void DoGCCollect ()
{
// Do nothing.
}
Probably the developer intended to write something similar and this is just a typo.
Looks like someone with a doomsday complex wrote it with connotations that they'd be ending the world with a 10 second timer...
This is not a good idea because you really ought to trust the garbage collector to do its job without being invoked specifically from your code.
99.9% of the time you never need to call the GC from your code.
First of all it is not a good idea to call GC.Collect(). Calling it multiple times has little effect.
However, you sometimes see the pattern of calling Collect(), then WaitForPendingFinalizers(), and then finally Collect() again. The idea behind this is to ensure that instances with finalizers are also reclaimed, as they will survive the first collection. Keep in mind tough that this will induce a delay in the application and it should very rarely be needed.

Categories