Invoking a Form UI Method From a Different Thread Using Delegates

The problem

How to interact with a UI when a long-running process is taking time and the UI becomes un-responsive.

Proposed Solution

The Invoke method of a form class provides a way to call a method on a form using a delegate.

Some tweaks

The code shown here uses an interface between the form and the presenter class; the presenter class is using this interface to call a function in the form but this mechanism is nothing to do with the Invoke method.

It is often required to update many UI forms from a different thread or in simple words a UI form should always remain responsive while a long-running process is called.

For this purpose .Net has the Invoke method in the Form class which takes a delegate as a parameter and can perform inter-thread message transfer (UI and another worker thread).

Here is the complete code:

---------------------------------------------------------------
Form Design consists of   - Button2, Label1 only
---------------------------------------------------------------

Form Code - 
---------------------------------------------------------------

Imports System.ComponentModel

Public Delegate Sub callInterProcess()

Public Class Form1
    Implements Interface1

    Public Sub setlabel() Implements Interface1.setlabel
        Label1.Text = "setted"
    End Sub

    Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim Obj As New Class1()
        Obj.onclick(Me)
        'TakeTime()
    End Sub
End Class
---------------------------------------------------------------


A presenter interface - the form class passes its instance to the presenter class and the presenter will use this interface
to call methods of the form class.
---------------------------------------------------------------
Public Interface Interface1

    Sub setlabel()

End Interface
---------------------------------------------------------------



A presenter class for the form -

---------------------------------------------------------------
Public Class Class1

    Dim obj As Form1

   Public Sub onclick(ByVal formObj As Interface1)
      'create a new thread
        Dim threader As New System.Threading.Thread(AddressOf TakeTime)
        'initialize forms interface reference
        obj = formObj
        threader.Start()
    End Sub

' Below method will take time to run, hence is executed in a separate thread.

    Public Sub TakeTime()
        System.Threading.Thread.Sleep(2000)
        obj.Invoke(New callInterProcess(AddressOf obj.setlabel))
        System.Threading.Thread.Sleep(20000)
    End Sub

End Class
---------------------------------------------------------------


Similar Articles