You should never call any methods/properties of the currently executing UI objects from the thread other then its associated UI thread.
Instead, you need to use the method
Invoke
or
BeginInvoke
of
System.Windows.Threading.Dispatcher
(for both Forms or WPF) or
System.Windows.Forms.Control
(Forms only).
You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[
^],
Problem with Treeview Scanner And MD5[
^].
See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[
^],
Control events not firing after enable disable + multithreading[
^].
Besides, I don't recommend using asynchronous APIs, as direct use of threading is more straightforward, simple, the logic is more linear; you got more control. Of course, you will need to use thread synchronization techniques (the less, the better, but you need to make sure your code is thread safe). But those thread synchronization techniques are always the same, while asynchronous code depends on particular APIs. I think that asynchronous APIs flourished when multithreading was not a commonplace as it is now.
—SA