views:

19

answers:

1

While going through this article I came across this statement -

If you are writing your own WPF objects, such as controls, all methods you use should call VerifyAccess before they perform any work. This guarantees that your objects are only used on the UI thread, like this

//Using VerifyAccess and CheckAccess 
public class MyWpfObject : DispatcherObject
{
    public void DoSomething()       
    {
        VerifyAccess();

        // Do some work
    }

    public void DoSomethingElse()
    {
        if (CheckAccess())
        {
            // Something, only if called 
            // on the right thread
        }
    }
}

I haven't seen this in any of the custom controls I have come across(as far as I remember).

Do you use this while building custom controls? Is it must to do this or just nice to have? Anyone ever faced any issue due to absence of this in your controls?

+1  A: 

Nah, never used this. And never noticed somebody use it in the context of Custom Controls. This rule is not followed in WPF Toolkit too.

This approach not only pollutes the code but also makes your custom control responsible for something it shouldn't care about. Consider situation where you always doing:

// Don't do this in all methods of your custom control!
public void Foo()
{
  if (!CheckAccess())
  {
    Dispatcher.Invoke(()=> Foo()); // Transit to UI Thread
    return;
  }
  // .. do work in UI.
}

At first glance this code looks fine. If you are not in UI thread, transit to UI thread, perform operation and return result. Right? - WRONG!

Problem 1. When you call Dispatcher.Invoke() you block calling thread until your request is processed by UI thread. This leads to poor performance. Of course, you can change this to Dispatcher.BeginInvoke() now your clients should be aware that their operation is done asynchronously. I.e. if client writes something to control, and then immediately reads it back there is no guarantee, that the operation already executed by UI thread.

Problem 2. Consider subsequent calls to the method Foo() from non UI thread. For example it's called in cycle:

// Somewhere not in UI
for (int i = 0; i < 1000000; i++)
{
  control.Foo(); // Looks good, but performance is awful!
}

Instead of blocking calling thread 1000000 times, developer could implement one check in the calling thread and transit to UI when necessary, instead of unconsciously jumping back and worth between threads.

Furthermore WPF will make this check for you when you access UI element from non-UI thread. It screams loud enough to crush application and be heard by developer who has done something wrong :).

Hope this helps.

Anvaka
@Anvaka: Yup, that is helpful. I just wanted to whether I am the only one not using it and missing something. Thanks.
akjoshi