I’ve been using SynchronizationContext for quite a while now. To me it is the best way to synchronize with the main thread. If you do a lot of winforms development like I do than you will know that you need to do this a lot. Blocking the UI is a nono.
SynchronizationContext has 2 methods that are of interest to us. Send and Post. According to the MSDN documentation.
- Post: When overridden in a derived class, dispatches an asynchronous message to a synchronization context.
- Send: When overridden in a derived class, dispatches a synchronous message to a synchronization context.
Meaning that Post is Async and Send is Synch. In most cases you won’t notice much difference between the two. And in most cases I would just recommend Post. Since in most cases you are just using the Synchronizationcontext to show something on the screen. I will however show you when Send is the better choice. And that is when you need to read from a control and need that result for later processing. This is a very simplified case but it makes the point quite nicely.
Lets make a form like this.
And now add this code.
Imports System.Threading Public Class Form1 Private _synchro As SynchronizationContext Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. _synchro = SynchronizationContext.Current End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Task.Run(Sub() DoMath(TextBox2, GetNumberSync) DoMath(TextBox3, GetNumberASync) End Sub) End Sub Private Function GetNumberSync() As Integer Dim returnvalue As Integer _synchro.Send(Sub() returnvalue = Convert.ToInt32(TextBox1.Text) End Sub, Nothing) Return returnvalue End Function Private Function GetNumberASync() As Integer Dim returnvalue As Integer _synchro.Post(Sub() returnvalue = Convert.ToInt32(TextBox1.Text) End Sub, Nothing) Return returnvalue End Function Private Sub DoMath(ByVal control As Control, ByVal x As Integer) _synchro.Post(Sub() control.Text = (x + 1).ToString End Sub, x) End Sub End Class
The result will be this.
So for the send method this is 2 because the line with the return will only be executed after the send has completed. For the post method this will be one because the returnvalue gets set sometime in the future which will most likely be after the Return has been called.
So something to be aware of.