OMG, Silverlight! Asynchronous is Evil! (or, Call me back when you got it)

Now we sit through Shakespeare in order to recognize the quotations. - Orson Welles

I just have to shake my head at this absolutely moronic thread on the Silverlight Forums promoting a "petition" to bring back synchronous webrequests in Silverlight. Really, it has all the elements of the old VB6 flame wars…

N.B. 8/18/2008: It looks like the moderators finally took the thread down; it was so full of hate posts and name-calling and ad-hominem attacks, its about time!

They just don't understand: Have you ever had your browser freeze up when requesting a page somewhere which request (or even a subrequest in the page, such as for advertising or an image) doesn't come back right away? Your browser turns white, your whole damned desktop is frozen, and you may need to get rid of IEXPLORE.EXE from within Task Manager just to free up your system (in rare cases you may actually have to shut down and reboot). This is what happens when a developer who doesn't know how to write asynchronous code issues a blocking, sync method call and then “something bad” happens. Remember - HTTP is NOT a reliable protocol!  

Since Silverlight's UI runs on a single thread and most all network code takes time to return (if it actually ever does return) it would be unacceptable if the Silverlight plug-in would just block waiting on an HTTP or Socket call -- thus blocking the UI of the host (your web browser). So, the Silverlight Team decided to only use the asynchronous model for all network related calls – whether WCF or WebService proxy calls, WebRequest, or WebClient. They simply implemented the same NPAPI plug-in architecture that all plug-ins must use.  It’s sad,  because a couple of “holier than thou” posters on that forum thread were quoting my statement from the paragraph above and telling me that I was stupid! Not stupid at all – the whole purpose of the plug-in architecture only permitting async requests is so that plug-ins would not be able to lock up the browser!

The bottom line is this: if Microsoft were to allow every petition-signing Tom, Dick and Harry blowhard / hotshot developer to make synchronous calls because they are too lazy and crybaby to learn how to do it better, there would DEFINITELY be a lot of very unhappy people with frozen browsers out there in SilverLand -- and guess who would get blamed? Microsoft!

I see that many are trying tricks like using ManualResetEvents and other threading primitives to try and “simulate” synchronous behavior. My advice? Don’t even bother to try – it’s so much easier and more professional to just learn how to write -- and THINK -- async. Your typical .NET developer is just so used to making a synchronous method call without ever taking the time to think about what will happen if it doesn’t come back -- it’s the Zen of the sound of a single hand clapping…

Have a look at the WebClient or WebHttpRequest class and see. There is no way to synchronously download content. You can write code with LINQ and inline delegates or Lambdas that “looks like” it’s synchronous, but it isn’t. You can try to use ManualResetEvents and other threading primitives to “trick” Silverlight into faking a  sync method call – but none of it will work. Of course, the majority of developers having 3 or even 5 years of experience with .NET have never even written an asynchronous method call -- and now they’ll have no choice but to learn how. And that -- is a good thing. Silverlight needs to be truly cross-browser. In order to do that, it must implement the standard NPAPI plug-in architecture, which dictates that ONLY async methods can be used. At least -- for now. Work with what you've got - don't flame.

Thanks to the Silverlight dev team for doing developers a big favor. I’m for “doing it in the callback”.

Comments

  1. well, You're right, async is better and safer than Sync ... But if Bad Programming in sl freeze Explorer for Sync calls, why they permit sync calls in Wpf (they blocks too the application).

    I'm working on a big project, we migrate other code in SL + Moss and we need to "translate" customer specific code in c# Code, in this customer specific code we've got something like:

    Foo() {
    save();
    close();
    }

    Can you write a parser who put the close method in the OnCompleted delegate ... is possible but everything is harder.

    I mean, Ok for best practice, but it's absolutely dangerous push with force in one direction without giving the possibility to dev to ... well ... make mistakes !

    ReplyDelete
  2. They allow sync calls in WPF because WPF applications do not normally run in the browser, they are desktop.

    ReplyDelete
  3. What about XBAP ? But again, I mainly develop Web App for intranets ... Silverlight give us the possibility to use a Windowed environment in a web environment ... but most of all ... why I cannot make mistakes ??? Is drag and drop for datagrid and datasource a Best Practice ?

    BTW ... I need them, and I didn't get the point ... if I put a while(true) in my code we got a blocking thread ... why don't remove while(true) statements?

    ReplyDelete
  4. Anonymous4:40 PM

    WOW, you're such a loser.

    You know full well that the argument is not about sync vs async.

    The argument is about who gets to do the async.

    You used to be someone that at least was respectable, but this intentional lying about the true focus of the conversation is odd at best, and attention seeking at worse.

    ReplyDelete
  5. @anonymous, Yes you are absolutely right. I am a real loser. And, the argument is indeed about "who gets to do the async". And the answer is, you - the developer - gets to do the async, and not the sync.

    Do you feel better now?

    ReplyDelete
  6. Anonymous1:50 AM

    It's amazing, you STILL don't get it. I'll let the readers decide, but providing a Sync function call allows us to make several sync calls WRAPPED in a thread to make it IMPOSSIBLE to hang the user interface.

    You contend that Microsoft should eliminate this method of programming. Well, that would be fine, and that's a valid(even if I don't agree) opinion.

    It's when you project your limitations on everyone else is where we part company.

    The problems you postulate don't exist in my world, they simply can't happen. I would be in favor of a switch, as they do on the server, to turn on a feature for advanced programmers.

    This lower common denominator approach is mentally weak, but then again, you don't tell the reader that MS eliminated sync for technical reasons, not the political ones you make up.

    Finally, you're not very truthful about your actions. You stated on the SL Forum that you were through talking about this.

    It's a shame you took this opportunity to poison the minds of those that may not be familiar with the full range of this topic.

    Either way, I do apologize for calling you a loser, that was over the top, and obviously not even true.

    Just remember, async is SAFE, no matter who does it, not ONLY if MS allows it.

    ReplyDelete
  7. Sorry, friend. It's you that don't "get it".

    You're not getting synchronous network method calls in Silverlight. There is no way the Silverlight development team (members of whom I've spoken to personally) will change their minds. The rationale has been laid out quite clearly, if you simply take the time to read it.

    So, you are wasting your time.

    ReplyDelete
  8. Anonymous7:44 PM

    This will be my last post on this, and I hope you get a clue one day.

    We ALREADY have sync calls available to us in SilverLight(through the bridge), we just wanted them in managed code, not the browser.

    I guess those sync calls should be removed as well, since some programmers(we won't mention names), can't program themselves out of a paper bag.

    I love the way you don't(or can't) address the issues, but come back with silly stuff. Then again... oh, why bother.

    Thanks for your time, and I do commend you on not censoring comments you don't agree with.

    I would be like the people I can't stand if I didn't at least give you credit for that.

    Could there actually be some hope for you(lol)?

    ReplyDelete
  9. Dude, whatever floats yer boat. You're not getting Sync networking calls in Silverlight managed code. Get over it.

    ReplyDelete
  10. No network Sync calls, for sure, but a way to simulate them with ManualResetEvents YES !

    We're working on it and we're writing an article on the Resynchronization of APM model of Silverlight. Sure it's not simple and but it's ok !

    ReplyDelete
  11. Heh. Let me know when you have your "workaround" ready. I won't hold my breath!

    ReplyDelete
  12. Anonymous5:51 AM

    PB: "They allow sync calls in WPF because WPF applications do not normally run in the browser, they are desktop."

    So what is the big difference between a WPF client/server app and a browser app running on the intranet?

    This has (sadly) become a purely religious discussion.

    Gianluca Gravina had some excellent technical points, but of course you never commented those...

    There are actually a lot of devs that have perfectly valid reasons to want to do sync (in background threads), but you just call them "crybabies".

    I wonder if you have never disagreed with a Microsoft decision? If so, can I call you crybaby too?

    At the very least, I think you are being pretty arrogant about this.

    ReplyDelete
  13. @miller - yes I have disagreed with MS decisions and will continue to do so when I feel it is appropriate. Regarding async-only in Silverlight, I believe that is a sound decision. You could certainly characterize my stance in this particular issue as arrogant. However, if you read through the SL forum threads on this, I believe I finally got my point across.

    ReplyDelete
  14. Here we've got it ... http://blogs.ugidotnet.org/ThinkingInGrava/archive/2008/08/28/resyncing-the-apm-model-of-silverlight.aspx Your feedback is appreciated.

    Cheers Gianluca

    ReplyDelete
  15. Anonymous9:24 AM

    Peter,

    To the best of my knowledge this is the first time I disagree with you enough to warrant leaving a reply.

    In this case, I believe MS has done the development community a disservice. I don't believe this is a question about who gets synch/asynch, or even about synch and asynch. It's a matter of lack of choice. Microsoft is trying to position SL for LOB work, and only having asynch for a choice makes this a more difficult programming model.

    Yes, getting a call blocked and the browser freezing is a bad thing, there's no doubt. But there are ways around this. If you can't fix it, then at least allowing a thread.sleep to work normally, in stead of blocking the application would be one of many ways the dev community can/could work around this issue.

    If thread.sleep didn't block then the browser wouldn't freeze while we waited on a return. And it would allow a developer to bail on a while...thread.sleep loop if the callback timeout occured.

    In the end, blocked browser is bad, lack of choice, and forcing dev teams into a new programming model is worse. It feels way lazy to me. MS didn't want to work through the difficulties around this, so they just punted on the issue.

    ReplyDelete
  16. @steve,
    In order for Silverlight to be truly "Cross - Browser" it has no choice but to use the current NPAPI browser plugin API. It is this API that forces the asynchronous behavior, not Microsoft. It is no different in Flash or similar plugins. So when W3C approves a better plugin architecture, you'll get what you want.

    ReplyDelete
  17. Anonymous6:55 PM

    I think the request here isn't necessarily a text-book implementation of synchronous calls, but rather Silverlight provide some sort of background container to simulate them via the asynchronous model they've established.

    It's true they (MS) need to follow the NPAPI standards, but nothing really stops them from putting anything on top of that short of an academic-only (vs pragmatic) mindset. They own the Silverlight standard.

    I think the real issue is that linear processing code becomes more difficult to follow if it is broken across two methods (the caller and the callback). This breaks encapsulation. So, in essence, MS is forcing one best practice while ignoring and sacrificing another one that is pretty substantial.

    There's probably still room to play in the sandbox to simulate the synchronous model within the (un)constraints of the asynchronous one. It's just that nothing clever or stable enough has been devised yet. :)

    ReplyDelete
  18. @anonymous,
    People (gravina et. al. above) have already taken pains to provide such a simulation and as far as I can see it has failed to gain much traction. If sychronous WebRequest calls had never been available to developers, I sincerely doubt there would be such a ruckus about all this.

    ReplyDelete
  19. Anonymous10:41 AM

    Well, synchronous requests were not a technology invented by Microsoft. In the case of their implementations, they were the carriage, not the horse.

    I'm pretty sure asynchornous calls are a much "newer" thing than synchronous in terms of API development. Asynchronous is a design pattern thats not nearly as common if you take Silverlight/Flash/Ajax technologies out of the equation.

    Most out-of-the-box web request APIs in languages inside and outside of the .Net spectrum block the process until the result comes back.

    To that end, I'm pretty sure it's a good bet that the only reason it doesn't exist in Silverlight is because they haven't figured out a good way yet to make it co-exist in the UI thread in a desirable way. It's not really about what's better or worse. They've hit a wall they haven't been able to climb over, so it's better for this particular flavor of technology at the moment.

    ReplyDelete
  20. @anonymous I agree with the first part of your comment, but not the second. At first BETAs they weren't using the NPAPI plugin architecture. Now that they are, there really isn't much room to maneuver because once you start implementing custom code outside of an accepted API, you have to code it for every browser and platform.

    ReplyDelete
  21. Anonymous6:11 PM

    They already are doing custom coding. Silverlight is a platform that's wrapping around that API to a great extent.

    That said, I can see the appeal of keeping the API one-to-one to the accepted standard. If that standard changes significantly and in a way that contradicts your wrapper significantly, you can be left with your pants down and be forced to make a breaking change in the established framework.

    I've messed around with Silverlight a bit today, and the main render loop is tied up pretty tight.

    I imagine the reason for this is so that it has complete control over when the rendering occurs (the lack of this being one of the largest contributor to over-drawing in win-forms). This is probably also the reason why Thread.Sleep() doesn't process events. Silverlight wants client code to completely exit so it can guarantee a cleanly rendered surface. That certainly isn't a bad thing from a presentation standpoint.

    At any rate, it's definitely in MS's hands to have a clean implementation of synchronous, and if what you've said is true about your communication with them, that's probably not in the cards.

    A render loop is occurring and running the show in terms of how much processor time is relinquished to other elements on the browser page. If they could find a way to process the remoting events without disrupting or causing any chaos to the rendering (and still allow processor cycles to slip into the webpage for it's sister elements in the DOM), a sync method could probably be implemented that would at least only impact the Silverlight app's performance. Of course, thats all based on speculation on how that API works. Maybe it simply doesn't give them the opportunity. I doubt it though. Especially since it's able to perform that call-back.

    Another way would probably be to somehow pre-process the source code on compile to invisibly re-write and implement the method running the remoting call to utilize the call-back and chain the next set of commands into it. I imagine implementing debugging and properly maintaining the scoping would be a nightmare there though. Reflection would be adversely affected too.

    Slowly, and reluctantly moving to the async camp. Like a lot of others, I really dislike being forced into a design pattern that breaks other ones.

    Looks like it's time to re-define the problem and approach it a different way.

    ReplyDelete
  22. Anonymous1:18 PM

    Two things, for what it's worth.

    First, it's tacky at best to rail against ad hominem attacks and in the same post, call those who disagree with you

    "Tom, Dick and Harry blowhard / hotshot developer to make synchronous calls because they are too lazy and crybaby to learn how to do it better..."

    Second, Microsoft is a business, and they will do whatever they think they need to do to please their customers. Remember their great new web site idea in VS2008? No actual web application, no way to smoothly add references, no real way to control the application. People hated it, some people loved it. Enough people hated it, and made their opinions known that MS included the web application method in a service pack shortly after release, and now it's back in VS2008 to stay.

    Yes, Microsoft will try to do what they think is right, but ultimately, in many cases, they will do what their customers want.

    Frankly, I think async is a good way to do many things. Sync is also a good way to do other things. I think it should be the choice of the developer. Yes, some will write bad code (hell I've written enough code that I'm not proud of myself), but I don't feel it's Microsoft's job (or yours, for that matter) to police the code out on the internet.

    Thanks,

    Morgan

    ReplyDelete
  23. If your browser is locking up because some silly programmer unintentionally or intentionally fucked up, and you have to reset your system for it, would it not be MUCH BETTER to just get a different browser that does not destroy your system state whenever something goes wrong?

    Just wondering...

    ReplyDelete
  24. @Martien, I am afraid you would be out of luck. Virtually all browsers implement the NPAPI specification which only allows asynchronous web requests via GET or POST verb.

    ReplyDelete
  25. Hi Peter,

    Chrome handles this issue pretty well I think (only the browser window that crashes will hang)
    I know it is not always possible to choose the browser you like (I have to code for IE right now, I'm feeling the pain also :( )
    But I think this is essentially an error of the browser and in the case of your OS (Windows? :) ) crashing, a bug in the OS.
    Anyway, I think it is quite possible to use synchronous calls and still have a stable webapp, but it all depends on the environment and the programmer.
    I am using AJAX mostly and it suited me well so far.
    But if someone else wants to use a different technique, why not let them?
    Our apps will win in the end anyway if the others are making the browser crash :)

    Best regards

    ReplyDelete
  26. Anonymous7:19 AM

    oh my god....am always shocked at us developers....

    Basically, whatever you can do in a sync call, like wrapping other methods etc, you can do asyncronously...All you need to do is write a little more handling code and trapping...I dont see anything wrong with that....

    If anything I dont really see the benefit of any sync calls in any application. If you want to tie up the interface until something is completed, then write that code yourself...you have greater control with async calls!...

    I do think sync programming is lazy, and I come from a VB5 background.....So we have to write a bit more code and take a bit more care..thats not a bad thing..its the user experience that counts, not how pretty our code is or in how little lines of code it took me to write!

    ReplyDelete
  27. Hi Andrew,

    I wonder if we should ask MS to leave out the complete XAML files thing (we should be able to generate the same applications without it, and we will have more control)
    And what the heck, why not remove session, Resources, Linq, ASP.NET and what else we come accross, since we can do it all programmatically.

    Suppose there is a component that creates a new thread, makes the async call, and makes it all appear like its synchronous.

    I challenge you to name one serious disadvantage of such component.

    Best regards,
    Martien de Jong

    ReplyDelete
  28. Wow, this thread got heated!! :) Come on guys, we're all on the same side here, save the battles for those PHP pricks.. ;) Anway, I can see why some would want synchronous methods (for example, for doing some really quick validation and then saving) but I love the fact that they didn't allow it because you can still work with it and your end-users will love you for it. It feels to me like async ajax without all the pain and suffering debugging in javascript..

    ReplyDelete
  29. "it’s the Zen of the sound of a single hand clapping"

    HEHE!

    I agree with Pete, async is a good thing.

    ReplyDelete
  30. Anonymous9:07 AM

    I hope that sync web calls will be supported in the future. This is a much needed feature, at least from the background threads.

    ReplyDelete
  31. @anonymous, I think it is highly unlikely that sync Http calls will be added. There is too much risk that dumb developers will cause a very bad user experience, and of course Microsoft will be blamed.

    ReplyDelete
  32. Thats all very sweet. But you couldn't possibly find the time to tell people HOW you use this async theory in practice?

    I rest my case..

    ReplyDelete
  33. @Bo,
    The Silverlight documentation and forums have many examples of the use of asynchronous methods. You can also look at http://www.eggheadcafe.com for some Silverlight articles I've written that have example downloadable source code.

    ReplyDelete
  34. Anonymous6:11 PM

    I am not the previous anonymous. But I would like to say that not having sync calls and delegate.BeginInvoke is bad for developers doing large real-time apps...

    and yes Peter. Denying the obvious and trying to diverge the conversation from your mistake to something like MS team will not add bla-bla-bla..

    There are 3 separate issues:

    1. lot of idiots from html/flash/php world will screw browser with sync calls and create large negative feedback. this is why sync calls were banned.

    2. not having precise control over async model in general is a problem for real developers working with async on large scale.

    3. you made mistake as the old Anon pointed - you deliberately removed the healthy argument and substituted the whole subject and painted it in circus-red. and then you deny you did it...

    Cheers

    ReplyDelete
  35. This comment has been removed by the author.

    ReplyDelete
  36. @Anonymous,
    Thanks for the sage advice, but the bottom line still remains: You're not going to get synchronous HTTP in Silverlight. In Silverlight 4.0, with elevated privileges and out of browser, you now will have basically a desktop app, and so different things can be done.

    ReplyDelete
  37. MikeM7:28 PM

    The main reason I was prompted to post was how utterly frustrating your attitude is (Peter). People aren't debating whether MS is adding synchronous methods or not. They are debating whether MS SHOULD add them. Your "last resort" retort of "yeah, well, too bad, you aren't getting them, get over it" is arrogant and irrelevant, and makes you sound like you have some sort of superiority complex talking to us like we are your 7 year old children. If that's all you have left, then a simple "yeah, they do have useful and legitimate uses but unfortunately it doesn't look like they be added" would be a more appropriate response.

    While I no-doubt agree that things like web service calls should be done asynchronously, as others have already pointed out it is extremely useful to have syncronous calls on a background thread. Dumb programmers can mess up an application in 10,000 ways. Sacrificing the utility of syncronous calls in appropriate situations to remove one of those ways is silly at best. For multi-stage processes, synchronous calls on a background thread are an order of magnitude easier to manage and understand.

    Your NPAPI argument has no grounds because it is very easy to wrap the async calls in a sync wrapper, as I've done many times. MS could do the same without changing their current implementation at all.

    ReplyDelete
  38. This comment has been removed by the author.

    ReplyDelete
  39. @MikeM, I guess you don't know me very well; I love controversy.

    Many developers have successfully "worked around" the asynchronous model, and almost universally, it is extremly ugly and non-productive to do so. Again, Microsoft is not going to give you native sync web calls in Silverlight.

    ReplyDelete
  40. MikeM8:26 PM

    @Peter:

    I don't have to know you very well to be frustrated by the attitude you are portraying in your comments. You are effectively stiffling a good debate and annoying people by saying "your points don't matter, because MS isn't adding it." People are trying to debate the merits of the sync model and you are dismissing their points by countering with "too bad."

    And I beg to differ on "ugly and non-productive" remark. Wrapping the socket connection class for sync calls is 10 line long:

    -Create ManualResetEvent
    -Call SendAsync (or ReceiveAsync)
    -ManualResetEvent.WaitOne()
    -Check state, fire exception if error

    -EndSend/EndReceive delegate: store error state and set ManualResetEvent

    ---

    Simple, easy, clean. Of course doing this for every single method in a web service would be painful and annoying, but that's what code generators are for. Generated code doesn't have to be pretty (and usually isn't). If MS just threw that into their web service code generator, it wouldn't need to be messy at all. It could even be optional - have a property on the service reference called "GenerateSyncMethods."

    In the case of the socket, you only have to do it once.

    If you have ever tried to chain 5+ asynchronous calls, you will no doubt know the benefits of doing it synchronously on a background thread. A good example of this is an encryption handshake exchange for sockets (which I recently had to implement) which had almost 10 potential back-and-forth chained calls with different branches and error checking in each one. The 10 line synchronous wrapper was a HUGE productivity boost, simplifying the exchange considerably, and allowed you to wrap the whole process in a single try-catch block.

    There are countless other useful scenarios, but I'm sure you know that, you are just being difficult and stubborn :)

    ReplyDelete
  41. @MikeM,
    Do you have a working sample of this code for Silverlight 3.0?
    You make it sound so simple, man!

    ReplyDelete
  42. MikeM9:00 PM

    I just quickly adapted this to the normal Silverlight socket, but our actual implementation is way different because we use our own platform-abstracted sockets to facilitate code sharing between Silverlight, .NET and CF. We have an abstraction layer that eliminates any platform differences which lets us code our library once and it just works on any of the .NET platforms.

    The Code (formatting is gonna be screwed I'm sure):

    public class SyncSocket
    {
    Socket asyncSocket;
    ManualResetEvent syncEvent = new ManualResetEvent(false);

    public SyncSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
    {
    asyncSocket = new Socket(addressFamily, socketType, protocolType);
    }

    public void Connect(EndPoint endPoint)
    {
    SocketAsyncEventArgs args = new SocketAsyncEventArgs { RemoteEndPoint = endPoint };

    args.Completed += (s, e) =>
    {
    if (e.SocketError != SocketError.Success)
    {
    throw new Exception("Connect Error: " + e.SocketError.ToString());
    }

    syncEvent.Set();
    };

    asyncSocket.ConnectAsync(args);
    syncEvent.WaitOne();
    syncEvent.Reset();
    }
    }

    You would just repeat this for Send and Receive.

    ReplyDelete
  43. @MikeM,
    that is great but I don't see any real implementation code, e.g. let's send something / receive something and then update the UI.
    Better yet, how about a sample that uses either WebClient or HttpWebRequest/Response as sockets are rarely used by Silverlight programmers? I mean, a complete working sample.

    ReplyDelete
  44. MikeM9:06 PM

    Er, sorry, minor correction regarding where the error is thrown:

    public void Connect(EndPoint endPoint)
    {
    SocketAsyncEventArgs args = new SocketAsyncEventArgs { RemoteEndPoint = endPoint };
    SocketError error = SocketError.Success;

    args.Completed += (s, e) =>
    {
    error = e.SocketError;
    syncEvent.Set();
    };

    asyncSocket.ConnectAsync(args);
    syncEvent.WaitOne();
    syncEvent.Reset();

    if (error != SocketError.Success)
    {
    throw new Exception("Connect Error: " + error.ToString());
    }
    }

    ---

    That way the error is thrown on your original calling thread.

    ReplyDelete
  45. @MikeM
    For example you could do something like this to simulate a sync WebClient call:

    public partial class Page : UserControl
    {
    public Page()
    {
    InitializeComponent();
    Thread thd = new Thread(new ParameterizedThreadStart(GetPage));
    thd.Start("Http://ittyurl.net/rss.aspx");
    }
    private void GetPage(object url)
    {
    string s= SyncWc.GetData((string)url);
    Dispatcher.BeginInvoke(() => text1.Text = s);
    }
    }


    namespace SyncWebClient
    {
    public static class SyncWc
    {

    private static ManualResetEvent mre = new ManualResetEvent(false);
    public static string GetData(string url)
    {
    string s = "";
    WebClient wc = new WebClient();
    wc.DownloadStringCompleted += (sender, e) =>
    {
    s = e.Result;
    mre.Set();
    };
    wc.DownloadStringAsync(new Uri(url));
    mre.WaitOne(1000);
    return s;
    }
    }
    }

    ReplyDelete
  46. MikeM9:27 PM

    Well that depends on what you are doing. I don't have anything I can show here at the moment, but I think this demonstrates the advantages pretty clearly:

    In the encryption handshake exchange within my library, you have:

    -DNS Lookup of host
    -Connect
    -Get list of supported encryption methods
    -Specify desired encryption method
    -Get the public key
    -Send verification code
    ...etc etc

    That requires:

    ConnectAsync, ConnectCompleted, ReceiveEncryptionMethodsAsync, ReceiveEncryptionMethodsCompleted, SendEncryptionMethodAsync, SendEncryptionMethodCompleted, ReceivePublicKey, ReceivePublicKeyCompleted, ....

    All those need error checking and complicated flow control, and it becomes a crazy mingled uber-chain that is impossible to maintain.

    Instead, it is much easier to create an asyncronous method called "ConnectAsync" which makes a background thread, performs all the above tasks synchronously on that thread, and then fires the completed delegate.

    The developer using my library can never tell the difference, but as I'm the one writing the library, internally chaining all those calls is a nighmare to maintain and comprehend. The application with the UI still only sees asynchronous calls, so from the updating UI perspective, nothing changes really.

    Perhaps I'll write up a complete example if I find some time, but I think the advantage is pretty clear in this case.

    ReplyDelete
  47. Would you guys mind posting the project / dll when you are ready?
    I think it adds some clicks.. I mean value.

    ReplyDelete
  48. This comment has been removed by the author.

    ReplyDelete
  49. http://ittyurl.net/kQHA.ashx That's a link to a solution article I just published, with a downloadable sample solution. Again, I don't recommend doing this, but what the heck.

    ReplyDelete
  50. Michael2:50 PM

    Unlike the other posters here, I will say that I prefer to learn to work within the given framework than trying to find workarounds. Kind of like a WCF developer trying to implement an old remoting design that normally isn't allowed in WCF.

    I find the async work a little bit harder to do: especially when in old days I would then want a user verification after a call. Now the security model requires I ask if they want it, then I do it, then I see if it works.

    On the other hand, the busy indicator is a great and simple way of making sure that the user does not do something while I'm out getting stuff. The only issue I've found so far is when initialization is loading 4 tables and I've no idea when all four are done. I've resorted to assigned bits in a byte with each one doing a lock, set, see if I'm done, release logic.

    The only issue I've encountered outside of the multi-get is that management cannot understand why coding takes so long when I've got to write at least two event handlers for each request.

    ReplyDelete
  51. Anonymous6:21 PM

    Might I recommend an approach to this thread where one might provide an example of when they feel they need sync call, then Peter can offer a recommendation to solve the same problem via async?

    Let me start...

    It is very typical pattern in LOB applications to cache results from a web service to memory. This allows us to prevent additional web service calls for the same data over and over again. For example, a list of states.

    It would be nice to
    1. Test if the states are cached in an application level variable.
    2. If not, then make a call to the web service to get the list of states.
    3. Upon return, save this list to the global variable for use by other LOB forms as needed.

    Of course, the above pattern can be accomplished using async.

    Now, imagine you have a LOB form. This form grabs data from a web service via async (say a list of customer addresses). The data only contains a list of stateID's which are used in the data. The data is bound to a gridview.

    The form allows the user to change the state for the customer via a combobox in the state column of the gridview. Now here is were the issue lays...

    In order to populate the state combobox with the complete list of states, the state web service routing above MUST complete before the form web service returns. If the states web service never returns, the combobox will not be populated.


    Now if this was not a LOB application, this might be OK; however, LOB users might have a UI which is not locked up, but they also have a non-functional form for them. This results in calls to tech support, and general unhappiness from the users. In this case, the users would rather have the UI stay inactive until it is ready to actually use.

    Peter, in this use case, what would the acceptable async approach to solve this problem.

    Thanks in advanced for your input.

    ReplyDelete
  52. Anonymous6:23 PM

    Might I recommend an approach to this thread where one might provide an example of when they feel they need sync call, then Peter can offer a recommendation to solve the same problem via async?

    Let me start...

    It is very typical pattern in LOB applications to cache results from a web service to memory. This allows us to prevent additional web service calls for the same data over and over again. For example, a list of states.

    It would be nice to
    1. Test if the states are cached in an application level variable.
    2. If not, then make a call to the web service to get the list of states.
    3. Upon return, save this list to the global variable for use by other LOB forms as needed.

    Of course, the above pattern can be accomplished using async.

    Now, imagine you have a LOB form. This form grabs data from a web service via async (say a list of customer addresses). The data only contains a list of stateID's which are used in the data. The data is bound to a gridview.

    The form allows the user to change the state for the customer via a combobox in the state column of the gridview. Now here is were the issue lays...

    In order to populate the state combobox with the complete list of states, the state web service routing above MUST complete before the form web service returns. If the states web service never returns, the combobox will not be populated.


    Now if this was not a LOB application, this might be OK; however, LOB users might have a UI which is not locked up, but they also have a non-functional form for them. This results in calls to tech support, and general unhappiness from the users. In this case, the users would rather have the UI stay inactive until it is ready to actually use.

    Peter, in this use case, what would the acceptable async approach to solve this problem.

    Thanks in advanced for your input.

    (p.s. another possible use case for sync might be user login process)

    ReplyDelete

Post a Comment

Popular posts from this blog

Some observations on Script Callbacks, "AJAX", "ATLAS" "AHAB" and where it's all going.

IE7 - Vista: "Internet Explorer has stopped Working"

FIREFOX / IE Word-Wrap, Word-Break, TABLES FIX

System.Web.Caching.Cache, HttpRuntime.Cache, and IIS Recycles

FIX: Requested Registry Access is not allowed (Visual Studio 2008)