Problems using Dispatcher.Invoke when trying to pass code back to the UI thread following a HTTPWebRequest

Unanswered Problems using Dispatcher.Invoke when trying to pass code back to the UI thread following a HTTPWebRequest

  • Saturday, April 14, 2012 12:39 PM
     
      Has Code

    Hi All,

    I'm writing my first Metro application. It's a port from a WP7 application and as part of it I do a HTTPWebRequest and in the Asynchronous callback pass some of the code to a dispatcher invoke to get it into the UI thread to do UI updates.
     
    This worked on my WP7 app, but I am struggling to port the functionality to Metro. Here is a snippet of the code I am using:           

                    try
                    {
                        thumb = basicImage;
                        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(value);
                        req.BeginGetResponse(updateThumb, req);
    
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e.Message);
                        Debug.WriteLine(e.StackTrace);
                    }
    
                }
    
            }
    
            public void updateThumb(IAsyncResult r)
            {
             
                Window.Current.Dispatcher.Invoke(Windows.UI.Core.CoreDispatcherPriority.Normal, (s, e) => { UIUpdateThumb(this, r); }, this, r);
            }
    
    
      
            public void UIUpdateThumb(Object sender, IAsyncResult r)
            {
    

    I am getting a NullReferenceException on the Invoke call with the message 'Object Reference not set to an instance of an object' but I don't for the life of me know what object it thinks is not set.
     
    I've tried several methods here. the WP7 code didn't use a method and just put a code block in the braces, but that gives the same problem when I do it here. I've investigated using the await keyword, but don't see how that would work with the BeginGetResponse call.
     
    Anyone have any ideas as I am stumped.

All Replies

  • Saturday, April 14, 2012 1:32 PM
     
     

    Hello Stuart,

    try this : req.BeginGetResponse(updateThumb, this);

    and retreive this Dispatcher instance from state

     public void updateThumb(IAsyncResult r)
           
    {
             // r.State or r.ObjectState or ... kind of that
                r.State.Dispatcher
    .Invoke(Windows.UI.Core.CoreDispatcherPriority.Normal, (s, e) => { UIUpdateThumb(this, r); }, this, null);
           
    }

    good luck

  • Saturday, April 14, 2012 7:31 PM
     
     

    Hi Vincent,

    I tried doing this. r doesn't have a state property, it does have a AsyncState property, but that does not have a Dispatcher.

    Still stumped

  • Saturday, April 14, 2012 7:44 PM
     
     

    Ok you ca cast the AsyncState property with the caller class and hope that caller have Dispatcher property :

    ((YourCallerClass)r.AsyncState).Dispatcher.Invoke(Windows.UI.Core.CoreDispatcherPriority.Normal,(s, e)=> { UIUpdateThumb(this, r);}, this, null);

  • Saturday, April 14, 2012 8:03 PM
     
     
    What would I need to extend my Class from to get a Dispatcher?
  • Saturday, April 14, 2012 9:05 PM
     
     
    Wath is the base class of your CallerClass (the class who call BeginGetResponse) ? It's is not Page ?
  • Saturday, April 14, 2012 10:02 PM
     
     

    Nope, it is a standalone class for storing data that I get from a web service.  The web service returns XML which I use to generate an object tree. Part of that process is taking references to images and getting the images into BitmapImage objects. The idea was to separate out the display functionality from the underlying data. Then the Data classes could be used for different visual apps.

    I guess the only solution is to push the setting of the images to the display (which given the UI thread is the only thing allowed to touch these objects is what I am supposed to be doing!)

  • Sunday, April 15, 2012 12:14 AM
     
     

    Ok, otherwise when you create this standalone class give the Dispatcher by the contructor !

    Another solution : create public static Dispatcher property on your App class and initilize it when your application started, after use this property for access the Dispatcher.

    Another solution : use event pattern so your UIUpdateThumb method must be raise the event.

  • Sunday, April 15, 2012 12:30 AM
     
     

    The problem I had was that this is in reality a chained asynchronous event. I had an Asynchronous event hen I called the webservice and got the XML data. then when I parsed that into my object tree I started to fetch the images from the remote web servers. As the thread doing the asynchronous get for the images was itself an asynchronous result it was also not on the UI thread so could not pass it in. So, I have left it that the Object tree just populates URI's and the gallery page in it's constructor calls a method to start fetching the images and passes in the UI dispatcher to the method which saves it privately in the instance so when the callback is called it has the UI dispatcher on hand.

    Thanks for all your help on this. I can't say I fully understand the paradigm we are expected to use here so more playing around is needed!

    Stu

  • Sunday, April 15, 2012 4:34 AM
     
     

    hi Stuart,

    You can just add static a "dispatcher" property in your class like,

    "public static Windows.UI.Core.CoreDispatcher dispatcher{get;set;};"

    and you need to 语法标注解释 initialize it in *.xaml.cs.

    I finished that in "OnLaunched" method, app.xaml.cs,  for myself.

    set "Your file name here".dispatcher = Windows.UI.Xaml.Window.Current.Dispatcher;

    Hope this would help you.

  • Sunday, April 15, 2012 2:42 PM
     
     

    You'r Welcome Stuart, good luck for your developpement