This operation can only occur on the UI Thread

So to avoid the JSON serialization length limit mentioned in a previous post, I have created a separate LoadMenuPage method that takes a menu file and a page number. The total number of pages is returned in the first LoadMenu call. At the moment, my client application loads all of the menus and merges them together into a single menu so the result is the same but this can take some time. The menus have to be limited to 10 menu items per web-service call and since there are 84 items in one of the menus, this requires 9 calls plus merge time.

I wanted to give some feedback to the user about this long running application so I tried starting an animation before the long call and then hiding it afterwards. This didn’t work because the long running call was executing on the UI thread so I moved the web-service invocation and merging logic to another thread. When it completes, it needs to populate a UI control which it can’t do if it’s not on the UI thread and there’s no Dispatcher in Silverlight yet. So I created a custom dispatcher using the HtmlTimer (which is marked obsolete but from research seems to be the only choice at the moment):

    public class CustomDispatcher
    {
        private Queue<Delegate> uiWork = new Queue<Delegate>();
        private HtmlTimer timer = new HtmlTimer();

        public void Start()
        {
            timer.Start();
        }

        public void InvokeOnUIThread(Delegate d)
        {
            uiWork.Enqueue(d);
        }

        private void OnTick(object sender, EventArgs args)        
        {
            if (uiWork.Count > 0)
            {
                Delegate d = uiWork.Dequeue();
                d.Method.Invoke(d.Target, null);
            }
        }

        public CustomDispatcher()        
        {
            timer.Interval = 100; 
            timer.Tick += new EventHandler(OnTick);
        }
    }

So all is looking good-ish, but then I hit another wall when I ran it up because I got the error I had been trying to avoid "This operation can only occur on the UI Thread":

UIThreadError

It seems the web-service proxy code requires an internal call to System.Windows.Browser.HtmlPage.get_DocumentUri() which needs to be executed on the UI thread. I haven’t tried the asynchronous BeginLoad in the proxy yet…

Advertisements

2 thoughts on “This operation can only occur on the UI Thread

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s