WP7- Confused about network communication, cross thread access, and continuation passing - c#

I'm porting a WPF app to WP7, and in the process I've had to refactor all the code that touches the network. The old code used the synchronous methods of the WebRequest object in background threads, but these methods no longer exist in WP7.
The result has been bewildering, and makes me feel like I'm doing something wrong. I've had to litter my views with thread dispatching code - the only alternative to this that I see is to supply the dispatcher to the lower tiers of the app, which would break platform-independence and muddy the boundary with the UI. I've lost the ability to make chained calls over the network from loops, and instead have callbacks invoking themselves. I've lost try/catch error handling and instead have OnSuccess and OnError callbacks everywhere. I'm now always unintentionally running code in background threads that are invoked by callbacks. I fondly remember the days when I was able to return values from methods.
I know continuation-passsing-style is supposed to be great, but I think all of the above has made the code more brittle and less readable, and has made threading issues more complex than they need to be.
Apologies if this question is vague, I'd just like to know if I'm missing some big picture here.

This is a limitation of Silverlight, which requires asynchronous network access (WCF proxy calls, WebClient, WebRequest, etc.). All synchronous network-reliant method calls have been removed from the framework.
To be crass: welcome to asynchronous programming. The only thing you did wrong was not making the calls asynchronous in the first place :)
I'm not 100% clear on the exact reasons MS removed the sync calls from web-dependent objects in Silverlight, but the explanations I hear always center on one or two reasons in some combination:
Browsers are architected on asynchronous network calls. Introducing synchronous calls would cause bad behavior/broken apps/crashes/etc.
If they gave everyone the "easy out" of making synchronous calls, the world would be littered with Silverlight apps that always froze while doing anything on the network, making Silverlight as a platform look bad.
That said - WCF proxies in Silverlight have the behavior that they always perform their callback on the calling thread. This is most often the UI thread, meaning you don't have to do any dispatching. I do not know if WebClient/WebRequest in Silverlight share this behavior.
As for the dispatcher, you could look into using a SynchronizationContext instead. The MVVM reference implementation in the MS Patterns and Practices Prism guidance does this - in the repository (data access class that actually makes calls out to an abstracted external service), they have a SynchronizationContext member that is initialized to System.Threading.SynchronizationContext.Current. This is the UI thread, if the constructor is called on the UI thread (it should be). All results from the service calls are then handled with mySynchronizationContext.Post.

Questions like this seem to behave like buses. You don't see any for ages then two come along almost at the same time. See this answer to a more concrete version of this question asked earlier today.
I have to I agree with you, continuation passing is tricky. A really useful technique is to borrow the C# yield return construct to create a machine that is able to maintain state between asynchronous operations. For a really good explanation see this blog by Jeremy Likness.
Personally I prefer a "less is more" approach so the AsyncOperationService is a very small chunk of code. You'll note that it has a single callback for both success and failure and there no interfaces to implement just a moderate delegate Action<Action<Exception>> which is typed as AsyncOperation to make it more convenient.
The basic steps to coding against this are:-
Code as if synchronous execution were possible
Create methods that return an AsyncOperation fpr only the smallest part that has to be asynchronous. Usually some WebRequest or WCF call but note just enough to get past the async bit, see me other answer for a good example.
Convert the synchronous "psuedo-code" to yeild these AsyncOperations and change the calling code to "Run" the resulting enumerable.
The final code looks quite similar to the synchronous code you might be more familar with.
As to accidentally running things on a background thread, that last answer included this useful AsyncOperation:-
public static AsyncOperation SwitchToUIThread()
{
return (completed => Deployment.Current.Dispatcher.BeginInvoke(() => completed(null)));
}
You can use that as the final yield in the run to ensure that code executing in the completed callback is executing on the UI thread. Its also useful to "flip" what is apparently synchronous code to be running on the UI thread when necessary.

Related

Should Task.Wait be deprecated?

I learnt the hard way that calling Task.Wait from a pool thread can lead to thread-starvation deadlock.
According to this MSDN article, in chapter 'deadlocks', we should obey these two rules:
Do not create any class whose synchronous methods wait for asynchronous functions, since this class could be called from a thread on the pool.
Do not use any class inside an asynchronous function if the class blocks waiting for asynchronous functions.
It seems the only place left for a legitimate use of Task.Wait is the Main function - I am exaggerating a bit here but you get the idea.
Why is Task.Wait still part of the .NET framework, seeing how dangerous it is?
Why is Task.Wait still part of the .NET framework, seeing how
dangerous it is?
Because you want to be able to synchronously block on a Task. Rarely, but you still do. As you said, Main is probably the most popular (and preferably the only) place where that would happen. That, and the fact that Microsoft is notorious for it's backwards compatability, so once this was introduced, it is highly unlikely to be deprecated or disappear from the BCL. Same goes for Task.WaitAll.
The real problem IMO starts when people don't properly read the documentation and don't understand the implications of calling such a method and end up misusing it. If you use it carefully, it does it's job great.
Another thing is the fact that you can't always go async all the way. Unfortunately, many times you have code, which is synchronous by signature, which can't be altered and needs to invoke an async method call. Yes, this is dangerous and discouraged by all and is considered an anti-pattern with async code, and I myself have answered at least a dozen question on SO where people end up deadlocking themselves and don't understand why, but the TPL authors still needed to make these type of calls possible.

Why does my BeginInvoke run synchronously

I have created a WCF application and in multiple places I am using BeginInvoke to run methods asynchronously. In some places it is asynchronous and in others it runs synchronously. Because the system is quite complicated I was hoping to just throw this high level question out there in the hope that someone knows a reason that BeginInvoke would be forced into synchronous running.
Possible reasons I have considered and believe are not the cause:
I ran out of ThreadPool Threads - I think at peak I use less than 20 threads.
I use locking across those threads stopping their concurrent executions - No synchronization is employed since each call is to a method on a separate WCF ServiceHost
A parent asynchronous method (which definitely is running asynchronously) calls many child BeginInvokes and you can't nest asynchronous invocations - I don't think that is a limitation
The parent asynchronous method is itself part of a WCF ServiceHost that is InstanceContextMode.PerSession and there is some limitation on it nesting asynchronous calls - Again, I don't think so, but FYI
Each child being called is a (different to the parent) WCF ServiceHost whose method I am calling is an instance of the same ServiceType and is run as InstanceContextMode.Single and ConcurrencyMode.Single. - Does that in some way impact the calling routine from running those asynchronously (I don't see why it would, but just in case)
Any ideas/solutions are much appreciated
I'd like to reference this quote regarding Delegate.BeginInvoke from Joe Duffy, in his book Concurrent Programming on Windows:
All delegate types, by convention offer a BeginInvoke and EndInvoke method alongside the ordinary synchronous Invoke method. While this is a nice programming model feature, you should stay away from them wherever possible. The implementation uses remoting infrastructure which imposes a sizable overhead to asynchronous invocation. Queue work to the thread pool directly is often a better approach, though that means you have to co-ordinate the rendezvous logic yourself.
I've done my own tests before, and the overhead can amount to many seconds when using these frequently. Perhaps this is not an answer to your question - because one would be almost impossible I think without seeing and debugging the code. This is rather a suggestion that you should take another look at your approach. Perhaps by queuing work to the ThreadPool directly, or using TPL (Task's / async&await).
If you're still set in finding the problem with the current code instead of revising it for a better strategy, and you still want help, you should find a way to reproduce your symptoms (that it is running synchronously) and provide code proving this.

Best solution for async chicken and egg story

I have been applying async best practices to all my libraries. Basically it means:
Only use async when it's truly async (libraries shouldn't lie)
Define a synchronous method if and only if you have a faster synchronous method that won’t dead lock.
Postfix all async methods with Async
I worked on a library that is synchronous by nature. This means it has only sync methods. If the user wants to run the work on a separate thread than the UI thread, they can do that themselves by using Task.Factory (responsibility of the caller).
However, inside a handler / method / extensibility point, we want to show the user a message box. This is an async method (for example, WinRT ShowDialogAsync). Then this gives us the following options:
A. Move everything to async (so we have the option to use await in our handlers and don't block anything).
public async Task MyMethodAsync()
{
await _messageService.ShowAsync();
}
The advantage is that users can add async methods without having to use .Wait(). The downside is that we are lying as a library (it's not truly async).
I have considered making everything async, but I don't think that's a good idea either. It would make all libraries lie but prepare them in case we would need it. Remember that making everything async out of the box has a (small) performance impact as well.
B. Inside the handler that requires user input, call .Wait()
public void MyMethod()
{
_messageService.ShowAsync().Wait();
}
The advantage is that this will allow us to use async code inside sync methods. But... it will never be callable from the UI-thread because the _messageService dispatches to the UI thread (but it cannot do that because it's still waiting for the method, resulting in a deadlock). This method will work when used inside a Task.Factory.Run block (but the responsibility is up to the end-user):
await Task.Factory.Run(() => MyMethod());
The question
I feel that both have pros and cons, but what would you choose? Let the library lie (A) or only allow the method to be called from a background thread (B)? Or maybe there are other options I've overseen.
If I go for A, it means I have to bump the major version every time (because it's actually a breaking change) whenever a user requests to convert a method to an async signature method.
Define a synchronous method if and only if you have a faster synchronous method that won’t dead lock.
I'd say "define a synchronous method if you have synchronous work to do". It doesn't matter how fast it is. The burden is on the caller to determine if it's too slow and they need to use Task.Run.
However, inside a handler / method / extensibility point
If this is an Observer kind of extensibility, consider just using events or observables.
However, it sounds like you want more of a Strategy kind of extensibility, where your invoking code must wait for and/or change its behavior based on the result of the callback.
I have considered making everything async, but I don't think that's a good idea either.
Async all the way is a guideline, not a strict command. It definitely applies in the 99% case, but this could be one of the exceptions. I would try not to make a library async just for the sake of a possibly-async Strategy pattern; I'd investigate other extension possibilities first. There is a valid argument for making the library async, if you view the Strategy callback as a dependency (the library would be async because its dependency is (possibly) async).
As you've discovered, there's no clean way to do sync-over-async. There are a few different hacks (such as blocking from a background thread), but you'll first need to decide whether you need to call your library from the UI thread.
If you do, then there's just two options: make the library async, or use a nested message loop. I strongly avoid nested message loops, especially in libraries; I'm just mentioning it for sake of completeness.
If you can impose on the user a requirement to only call the library from a non-UI thread, then you can apply other hacks. E.g., blocking the background thread.
There's not an easy solution, sorry.
As far as me personally... if the library needs an async Strategy, then I would lean towards making the library async. But it does depend on what kind of library it is, whether there were backwards-compatibility issues, etc. And the first thing I'd look into is a different kind of extensibility point.
as you can read here :
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
Async All the Way
Asynchronous code reminds me of the story of a fellow who mentioned that the world was suspended in space and was immediately challenged by an elderly lady claiming that the world rested on the back of a giant turtle. When the man enquired what the turtle was standing on, the lady replied, “You’re very clever, young man, but it’s turtles all the way down!” As you convert synchronous code to asynchronous code, you’ll find that it works best if asynchronous code calls and is called by other asynchronous code—all the way down (or “up,” if you prefer). Others have also noticed the spreading behavior of asynchronous programming and have called it “contagious” or compared it to a zombie virus. Whether turtles or zombies, it’s definitely true that asynchronous code tends to drive surrounding code to also be asynchronous. This behavior is inherent in all types of asynchronous programming, not just the new async/await keywords.
“Async all the way” means that you shouldn’t mix synchronous and asynchronous code without carefully considering the consequences. In particular, it’s usually a bad idea to block on async code by calling Task.Wait or Task.Result. This is an especially common problem for programmers who are “dipping their toes” into asynchronous programming, converting just a small part of their application and wrapping it in a synchronous API so the rest of the application is isolated from the changes. Unfortunately, they run into problems with deadlocks. After answering many async-related questions on the MSDN forums, Stack Overflow and e-mail, I can say this is by far the most-asked question by async newcomers once they learn the basics: “Why does my partially async code deadlock?”

Using Task.WaitAll in a WCF method

I have a .NET 4.5.1 WCF service that handles synchronization from an app that will be used by thousands of users. I currently use Task.WaitAll as shown below and it works fine but I read that this is bad, can cause deadlocks, etc. I believe I tried WhenAll in the past and it didn't work, I don't recall the issues as I'm returning to this for review again just to make sure I'm doing this right. My concern is whether or not the blocking is needed and preferred in this use, a WCF service method hence why the WaitAll appears to work without issue.
I have about a dozen methods that each update an entity in Entity Framework 6 processing the incoming data with existing data and making the necessary changes. Each of these methods can be expensive so I would like to use parallelism mainly to get all methods working at the same time on this powerful 24 core server. Each method returns as Task as wraps its contents in Task.Run. The DoSync method created a new List and adds each of these sync methods to the list. I then call Task.WaitAll(taskList.ToArray()) and all works great.
Is this the right way of doing this? I want to make sure this method will scale well, not cause problems, and work properly in a WCF service scenario.
In high-scale services it is often a good idea to use async IO (which you are not - you use Task.Run). "High scale" is very loosely defined. The benefit of async IO on the server is that it does not block threads. This leads to less memory usage and less context switching. That is all there is to it.
If you do not need these benefits you can use sync IO and blocking all you like. Nothing bad will happen. Understand, that running 10 queries on background threads and waiting for them will temporarily block 11 threads. This might be fine, or not, depending on the number of concurrent operations you expect.
I suggest you do a little research regarding the scalability benefits of async IO so that you better understand when to use it. Remember that there is a cost to going async: Slower development and more concurrency bugs.
Understand, that async IO is different from just using the thread-pool (Task.Run). The thread-pool is not thread-less while async IO does not use any threads at all. Not even "invisible" threads managed by the runtime.
What I often find is: If you have to ask, you don't need it.
Task.WhenAll is the non-blocking equivalent of Task.WaitAll, and without seeing your code I can't think of any reason why it wouldn't work and wouldn't be preferable. But note that Task.WhenAll itself returns a Task which you must await. Did you do that?

C#: How can i elegantly and or simplistically make cross threaded calls?

i have a tcp server that, when a client connects, it makes a new thread and adds them to it but everytime i try to access information about the connection or anything about it, say even keeping a count of how many clients are connected, i get a cross-thread illegal exception or something like that.
ive read several tutorials on things called delegates, invoking and reflection but all the examples or tutorials simply confuse me as doing one invoke a certain way fails in another.
is there an elegant or simplistic way of doing this? do i need to learn how to do something else first? or am i just making things way more complex than they are? any suggestions, links or tips are most appreciated and accepted.
I suppose you go directly to the UI from your client connection thread. This is not good. Instead, consider using some variation of MVP pattern to decouple presentation logic from views. Thus, your "connection threads" will talk to some intermediary, presenters will talk to the same intermediary and just hand off some data for view to display.
As far as cross-thread operations are concerned, particulary UI thread operations, I find SynchronizationContext to be very useful in cicrumstances when you want to marshal a call from a non-UI thread to the UI thread. See this article for more in-depth discussion.
I guess you get this cross thread exception since you are trying to update screen elements from your threaded code. If you need to do that you can get a simple solution using anonymous method.
Say that you want to add an item to a listbox called ListBoxLog. This code would do the trick from any thread:
ListBoxLog.Invoke((MethodInvoker)delegate { ListBoxLog.Items.Add("Done"); });
There's also a property to check .InvokeRequired you can check to see if invocation is nessecary. You would typically check that property in a function that could be called by both the main UI thread and any background thread.
You can also use BeginInvoke like I did with Invoke. BeginInvoke is totaly asynchronous and does not wait for the code in the delegate to finish.
Using delegates and events.
That would be my best answer.
http://www.codeproject.com/KB/cs/Cross_thread_Events.aspx
There are plenty of examples online to help you:
http://www.google.com/search?q=tcp+server+multi+thread
When using C#, the Concurrency and Coordination Runtime (CCR) also has a sample about implementing multithreaded tcp server. The CCR allows a much better paradigm to implement parrallel processing, it simplifies a lot of the standard multi-threading code.

Categories