网上有很多跨线程访控件的方法, 参考并利用反射进行封装, 供日后调用方便封装代码:
Imports System.Windows.Forms
Imports LEAF.BusinessObject
'Cross-thread access control
'跨线程访控件的方法
Namespace Forms
Public Class CrossThreadAccessControl
'访问类型
Enum AccessType
REPLACE '复写
APPEND '追加
End Enum
'定义Windows控件控制代理
Public Delegate Sub AccessControlDelegate(ByVal control As Control, _
ByVal obj As Object, _
ByVal tag As Object, _
ByVal type As AccessType)
Public Shared Sub AccessControl(ByVal control As Control, _
ByVal obj As Object, _
ByVal tag As Object, _
Optional ByVal type As AccessType = AccessType.REPLACE)
'直接将内容添加到窗体的图片控件上
If control.InvokeRequired = False Then
'访问图片
If control.GetType.ToString = GetType(PictureBox).ToString Then
Try
CType(control, PictureBox).Image = CType(obj, Drawing.Image)
CType(control, PictureBox).Tag = tag
Catch ex As Exception
LeafEventLog.AppLogToFile("Cross-thread access to Image - " + ex.ToString)
End Try
'访问文本
ElseIf control.GetType.ToString = GetType(TextBox).ToString Then
Try
Select Case type
Case AccessType.APPEND
CType(control, TextBox).Text = CType(control, TextBox).Text + CType(obj, String) + vbCrLf
Case AccessType.REPLACE
CType(control, TextBox).Text = CType(obj, String) + vbCrLf
Case Else
CType(control, TextBox).Text = CType(obj, String) + vbCrLf
End Select
CType(control, TextBox).Tag = tag
Catch ex As Exception
LeafEventLog.AppLogToFile("Cross-thread access to TextBox - " + ex.ToString)
End Try
'访问文本标签
ElseIf control.GetType.ToString = GetType(Label).ToString Then
Try
CType(control, Label).Text = CType(obj, String)
CType(control, TextBox).Tag = tag
Catch ex As Exception
LeafEventLog.AppLogToFile("Cross-thread access to Label - " + ex.ToString)
End Try
Else
'其他暂不支持
LeafEventLog.AppLogToFile("Cross-thread access UI - Not Support current control type !")
End If
Else
'通过使用Invoke的方法,让子线程告诉窗体线程来完成相应的控件操作
Dim acess As AccessControlDelegate = New AccessControlDelegate(AddressOf AccessControl)
'使用控件的Invoke方法执行AccessControl代理(其类型是AccessControlDelegate)
control.Invoke(acess, New Object() {control, obj, tag, type})
End If
End Sub
End Class
End Namespace
调用代码:
Public Sub SvrPulseEcho(ByVal msg As String)
'Get server status logs
Dim _msg As String '= txtLog.Text
'Get system date time
_msg = Format(Now, "yyyy-MM-dd HH:mm:ss") + " : " + msg + vbCrLf
'截去超长的字符串
If Len(txtLog.Text) > 10240 Then
_msg = Microsoft.VisualBasic.Left(txtLog.Text, 512)
End If
'回显当前的心跳
CrossThreadAccessControl.AccessControl(Me.txtLog, _msg, Nothing, _
CrossThreadAccessControl.AccessType.APPEND)
End Sub
记日志的方法请参考
Shared ReadOnly Property AppFullName() As String
Get
Return Process.GetCurrentProcess().MainModule.FileName
End Get
End Property
Shared ReadOnly Property AppName() As String
Get
Dim _appFullName As String = AppFullName
Dim index As Integer = _appFullName.LastIndexOf("\")
Return _appFullName.Substring(index + 1, _appFullName.Length - index - 1)
End Get
End Property
Shared ReadOnly Property AppLogFullPath() As String
Get
Dim _appName As String = AppName
Return AppDomain.CurrentDomain.SetupInformation.ApplicationBase & "\" & _
_appName.Substring(0, _appName.LastIndexOf(".")) & "Log" & "\"
End Get
End Property
Shared ReadOnly Property AppLogFullName() As String
Get
Dim _appName As String = AppName
Return AppDomain.CurrentDomain.SetupInformation.ApplicationBase & "\" & _
_appName.Substring(0, _appName.LastIndexOf(".")) & "Log" & "\" & _
DateTime.Now.ToString("yyyyMMdd") & ".log"
End Get
End Property
Public Shared Sub AppLogToFile(ByVal message As String)
'Create Direction for log file
Dim dir As String = AppLogFullPath
If Directory.Exists(dir) = False Then
Dim returnValue As DirectoryInfo = Directory.CreateDirectory(dir)
End If
Dim current As String = AppLogFullName
FileUtility.TextFileHelperC.WriteLine(current, DateTime.Now.ToLongTimeString() & " : " & message)
End Sub
写文本行的方法请参考
Public Shared Function WriteLine(ByVal fileFullPath As String, _
ByVal line As String) As Boolean
Dim path As String = fileFullPath
Dim rtn As Boolean = False
' This text is added only once to the file.
'File is not exist, create new file
Try
If File.Exists(path) = False Then
Using sw As StreamWriter = New StreamWriter(File.Create(path), Encoding.UTF8)
sw.WriteLine(line)
sw.Close()
End Using
Else
Using sw As StreamWriter = New StreamWriter(fileFullPath, True, Encoding.UTF8)
sw.WriteLine(line)
sw.Close()
End Using
End If
Catch ex As Exception
Return False
End Try
Return True
End Function