1

I know that I cannot make a true synchronous call in Windows Phone 7. However, I'm trying to at least block the threads from processing until the async call is made or there is a timeout. I've tried the following, but it seems like my app just ignores it, abandons the call, and doesn't return back. Any ideas why?

I'm trying to update a value using a Value Converter during binding.

public ManualResetEvent _event;

public void GetSync()
{
    _event = new ManualResetEvent(false);

    var wc = new WebClient();
    wc.OpenReadCompleted += new OpenReadCompletedEventHandler(ReadCompleted);
    wc.OpenReadAsync(new Uri("My URL"));

    // block until async call is complete
    _event.WaitOne(5000);
}

private void ReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    var serializer = new XmlSerializer(typeof(MyFormatter));
    // The property below is accessed back in the Value Converter for binding
    StronglyTypedObject = (StObject)serializer.Deserialize(e.Result);
    _event.Set();
}
Jason N. Gaylord
  • 7,910
  • 15
  • 56
  • 95
  • 1
    I can't test right now, but if I remember correctly the callback of the `WebClient` uses the UI thread, so it cannot work if you're blocking it. To confirm whether that's your issue or not, try using a `HttpWebRequest` instead (or execute `GetSync` in a separate thread) – Kevin Gosse Apr 18 '13 at 07:53
  • I love the down votes without a comment. Seriously. :) – Jason N. Gaylord Apr 19 '13 at 02:22
  • @KooKiz - Thanks for the comment. I thought all WP7 calls including WebClient where async: http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=VS.95%29.aspx – Jason N. Gaylord Apr 19 '13 at 02:23
  • They are. But once the async call is done, the WebClient uses the UI thread to execute the callback, while most async functions use a random thread for that. It's an approximation but you can say that OpenRead is asynchronous while ReadCompleted is synchronous. I'm not sure why it has been implemented like that, it can be pretty dangerous like your example demonstrates. – Kevin Gosse Apr 19 '13 at 06:09
  • So, how can I then get a synchronous call to update the UI appropriately? Is there a way I can refresh the UI when the callback occurs? – Jason N. Gaylord Apr 22 '13 at 14:49
  • 1
    Usually, locking the UI is considered bad practice. Especially if you're doing a web call: if the network quality is poor (and it occurs quite often on a mobile phone), the request could time out and lock the UI for a long time (up to 5 seconds in your case, since you've put a timeout on the lock). But if you really want to do that, you could use a `HttpWebRequest` instead of the `WebClient`, keep the same locking mechanism, and put the UI-updating code right after `_event.WaitOne` (since `StronglyTypedObject` is a property, you can access it) – Kevin Gosse Apr 22 '13 at 15:06
  • I'll try that out. What's the best practice? Find some other way to get that info to update the UI? For instance, if I'd like to grab an image from the web, what's the best way to bind this to a list? – Jason N. Gaylord Apr 22 '13 at 20:49
  • The problem I'm running into is getting the value pulled back to the ValueConverter to update the appropriate field. Sorry, I should have stressed that more. – Jason N. Gaylord Apr 23 '13 at 04:02
  • 1
    You mean, the ValueConverter is downloading the picture? You shouldn't, the ValueConverter is designed to handle short operations. Either handle the download in the model object you're binding to the list (expose a BitmapSource property and use the INotifyPropertyChanged interface to update it when the download has ended), or make a custom control that encapsulates the Picture control and adds all the download/deserializing logic. I'd recommend the first solution: the second one is a tad easier for the memory management, but putting business code in a control is a bad idea. – Kevin Gosse Apr 23 '13 at 05:58
  • Nope, the ValueConverter was returning a path to the image. I guess I can try to load that in the model. Let me take a stab and I'll post back. – Jason N. Gaylord Apr 23 '13 at 12:59

0 Answers0