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.