A generic winform skeleton support interactive UI during large job process

It is quite annoying when a .net program try to update user interface control from a seperate long run task thread.

The runtime give me exception “Control control name accessed from a thread other than the thread it was created on.”

If it is in visual studio 2005, a lot of place recommend use "BackgroundWorker" to solve the problem.

But it is also not flexiable, It works fine with progressbar control only. If I need to display something on textbox, It is not straigt forward. For example, I want to change textbox background color.

I created my own skeleton code which can easily access any user interface control from seperate thread.

The key part is in UpdateUI_handler subroutine.

And if you want to access one control, you just need tell

  • what control you want to access,
  • what property of the control you want to access,
  • and what value you want to set.

That is very easy approach to solve the problem.

Below is my sample application snapshot

A generic winform skeleton support interactive UI during large job process_第1张图片

 

You can follow 3 steps below to create the project

  1. Create vb winform application in visual studio 2005.
  2. Drag a textbox, a label, a progressbar and a button on the form.
  3. Copy the code below and overwrite form1.vb

 

   1:  Imports System
   2:  Imports System.Threading
   3:  Imports system.reflection
   4:  Public Class Form1
   5:      Delegate Sub UpdateUI(ByVal UpdateParameter As UIUpdateParameter)
   6:      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   7:          Dim index As Int32
   8:          index = 10
   9:          Me.ProgressBar1.Maximum = index
  10:          Debug.WriteLine("Main Form thread: " & AppDomain.GetCurrentThreadId)
  11:          Dim thread As Thread
  12:          thread = New Thread(AddressOf DoTask)
  13:          thread.IsBackground = True
  14:          thread.Start()
  15:      End Sub 
  16:   
  17:      Private Sub UpdateUI_handler(ByVal UpdateParameter As UIUpdateParameter)
  18:          Debug.WriteLine("Update progress bar thread: " & AppDomain.GetCurrentThreadId)
  19:          Dim theControlType As Object = Nothing
  20:          Dim theControl As Control = Nothing
  21:          For Each p As System.Reflection.PropertyInfo In Me.Controls(UpdateParameter.controlName).GetType().GetProperties()
  22:              theControl = Me.Controls(UpdateParameter.controlName)
  23:              theControlType = Convert.ChangeType(theControl, theControl.GetType)
  24:              If Not IsNothing(p.GetValue(theControlType, Nothing)) Then
  25:                  If UCase(p.Name.ToString) = UCase(UpdateParameter.PropertyName) Then
  26:                      p.SetValue(theControlType, Convert.ChangeType(UpdateParameter.value, p.PropertyType), Nothing)
  27:                  End If
  28:              End If
  29:          Next
  30:      End Sub
  31:      Private Sub DoTask(ByVal t)
  32:          For i As Integer = 1 To 10
  33:              Thread.Sleep(500)
  34:              Debug.WriteLine("Do Task thread: " & AppDomain.GetCurrentThreadId) 
  35:   
  36:              Dim uiUpdate2 As UpdateUI
  37:              uiUpdate2 = New UpdateUI(AddressOf UpdateUI_handler) 
  38:   
  39:              Dim UpdateParameter As New UIUpdateParameter
  40:              UpdateParameter.controlName = "ProgressBar1"
  41:              UpdateParameter.PropertyName = "value"
  42:              UpdateParameter.value = i
  43:              Me.Invoke(uiUpdate2, UpdateParameter) 
  44:   
  45:              UpdateParameter.controlName = "Label1"
  46:              UpdateParameter.PropertyName = "Text"
  47:              UpdateParameter.value = i
  48:              Me.Invoke(uiUpdate2, UpdateParameter) 
  49:   
  50:              UpdateParameter.controlName = "Textbox1"
  51:              UpdateParameter.PropertyName = "backcolor"
  52:              If i Mod 2 = 0 Then
  53:                  UpdateParameter.value = Color.Blue
  54:              Else
  55:                  UpdateParameter.value = Color.Yellow
  56:              End If 
  57:   
  58:              Me.Invoke(uiUpdate2, UpdateParameter)
  59:          Next i
  60:      End Sub
  61:  End Class 
  62:   
  63:  Public Class UIUpdateParameter
  64:      Public controlName As String
  65:      Public PropertyName As String
  66:      Public value As Object
  67:  End Class 

转载于:https://www.cnblogs.com/yangbin990/archive/2009/09/05/1560357.html

你可能感兴趣的:(A generic winform skeleton support interactive UI during large job process)