当前位置: 动力学知识库 > 问答 > 编程问答 >

vb.net form freezing, threading, events and a confused noob

问题描述:

I’ve got a problem with form freezes when loading the form from an event. I bet it got to do with threading but sadly I don’t know enough about it to fix it myself :(

Let me explain my project:

I've got a class that hooks into networking events (like new connected e.g.),

which I’ve instanced in a form and declared some events from it.

Public Netstat As New aaNetTool.clsNetworkStatus

AddHandler Netstat.NetworkChanged, AddressOf Network_Changed

Sub Network_Changed()

End Sub

Then I’ve written another class, clsMessage which I want to use to show forms with notifications.

Public Class clsMessage

Private myForm As frmDisplayMessage

Public Sub New(ByVal Title$, ByVal Text$, Optional btnYesAction As Action = Nothing, Optional ByVal ShowTimeSec% = 10)

myForm = New frmDisplayMessage

myForm.Text = Title

myForm.lblText.Text = Text

(...)

myForm.Show()

(...)

End Sub

Now I create a new notification window for debugging purposes with a button from the main form like this:

Dim myMsg As New clsMessage("title", "text", AddressOf MapNetworkdrives, 30)

This works like a charm.

But when I call the notification from my declared event:

Sub Network_Changed()

Dim myMsg As New clsMessage("title", "text", AddressOf MapNetworkdrives, 30)

End Sub

The form with the notification appears but is empty and freezed.

As said before I think this may have to do with my code running on different threads but I just can't figure out how to solve this :(

Thanks in advance for your Time,

Lunex

网友答案:

The clsNetworkStatus.NetworkChanged event appears to be raised from a background thread. Since your notification form is part of the UI you must invoke so that it is executed under the UI thread.

The InvokeRequired property tells you whether you need to invoke or not, so if it's False your code is already running on the UI thread.

You can create an extension method to do the checking for you:

Imports System.Runtime.CompilerServices

Public Module Extensions
    <Extension()> _
    Public Sub InvokeIfRequired(ByVal Control As Control, ByVal Method As Action)
        If Control.InvokeRequired = True Then
            Control.Invoke(Method) 'Invoke the method thread-safely.
        Else
            Method.Invoke() 'Call the method normally (equal to just calling: 'Method()').
        End If
    End Sub
End Module

Then you'd use it like this:

Sub Network_Changed()
     Me.InvokeIfRequired(Sub()
                                           Dim myMsg As New clsMessage("title", "text", AddressOf MapNetworkdrives, 30)
                                       End Sub)
End Sub
分享给朋友:
您可能感兴趣的文章:
随机阅读: