来自另一个类

时间:2017-12-06 19:03:07

标签: vb.net

如何从另一个类和线程调用WindowsFormsSynchronizationContext可能是我自己的愚蠢,但我已经到处搜索,无法理解。

如果我将worker和代码放在Form1的主体中,它确实有用。

Form1:

Public Shared UIContext As WindowsFormsSynchronizationContext
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    UIContext = WindowsFormsSynchronizationContext.Current
    Dim StartClock As New SendtoUI
End Sub
Public Sub updatelable(incomingText As String)
    Label1.Text = incomingText
End Sub

测试类:

Public Class SendtoUI
    Private lastUpdated As DateTime = DateTime.Now
    Private backgroundTimer As System.Timers.Timer
    Public Sub New()
        backgroundTimer = New Timers.Timer(1000)
        AddHandler backgroundTimer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf backgroundTimer_Elapsed)
        backgroundTimer.Start()
    End Sub

    Private Sub backgroundTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
        lastUpdated = DateTime.Now

        Form1.UIContext.Post(Sub()
                                    Form1.updatelable(lastUpdated.ToLongTimeString())
                                End Sub, Nothing)
    End Sub
End Class

基于以上,

  

Label1.Text = incomingText

该行已执行,但标签未更新。可能很简单,但我很难过。

感谢您的帮助!

-TD

好的,我明白了,感谢Jimi,我更新了我的最终结果,并希望它可以帮助别人!

简单form1如下:

    Imports System.Threading

    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim TestTHreadUI As New ThreadedBackground(SynchronizationContext.Current, New SendOrPostCallback(AddressOf UpdateUI))
        End Sub
        Public Sub UpdateUI(incomingText As Object)
            Label1.Text = incomingText.ToString
        End Sub
    End Class

ThreadedBackground类:

Imports System.Threading

    Public Class ThreadedBackground
        Private backgroundTimer As System.Timers.Timer
        Public Sub New(UIContext As SynchronizationContext, UpdateAddress As SendOrPostCallback)
            SyncContext = UIContext
            SyncCallback = UpdateAddress
            backgroundTimer = New Timers.Timer(1000)
            AddHandler backgroundTimer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf backgroundTimer_Elapsed)
            backgroundTimer.Start()
        End Sub

        'SynchronizationContext used for Posting
        Public Property SyncContext As System.Threading.SynchronizationContext
        'The Object Callback address to call
        Public Property SyncCallback As System.Threading.SendOrPostCallback

        Private Sub backgroundTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)

            'SyncContext.Post(SyncCallback, CType(DateTime.Now.ToLongTimeString, Object))   ' using passed in SendOrPostCallback(SyncCallback)
            SyncContext.Post(New SendOrPostCallback(Sub() Form1.UpdateUI(DateTime.Now.ToLongTimeString)), Nothing) ' Not using SendOrPostCallback(SyncCallback), Direct call to form1 Sub using lambda 
            'SyncContext.Post(New SendOrPostCallback(Sub() Form1.Label1.Text = DateTime.Now.ToLongTimeString), Nothing) ' Not using SendOrPostCallback(SyncCallback), Direct call to form1 Control using lambda 

        End Sub
    End Class

1 个答案:

答案 0 :(得分:0)

我会考虑在你的班级中避免对特定对象(本例中为Form)的静态引用 一种方法是为您的类添加一些可以保存该引用的属性。

您的代码可以编辑为:

cnxn = pyodbc.connect(cnxn_str)
cursor = cnxn.cursor()

#Sample select query
print 'Testing db connection...'
cursor.execute("SELECT @@version;") 
row = cursor.fetchone() 
while row: 
    print row[0] 
    row = cursor.fetchone()

您的班级有新属性:

Imports System.Threading

Public Class Form1

   Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button1.Click

      Dim StartClock As New SendtoUI
      StartClock.SyncContext = System.Windows.Forms.WindowsFormsSynchronizationContext.Current
      StartClock.SyncCallback = New System.Threading.SendOrPostCallback(AddressOf Me.updatelable)
   End Sub

   'Delegate signature
   'Public Delegate Sub SendOrPostCallback(state As Object)

   Public Sub updatelable(incomingText As Object)
      Label1.Text = incomingText.ToString
   End Sub
End Class