ОК, я вижу, в чем проблема.Я предполагаю, что вы вызываете один из SetDisplayText
методов из сценария PS.Вам нужно защитить тех, у кого есть проверки на InvokeRequired
и IsHandleCreated
, плюс вам необходимо обеспечить синхронизацию при начальном отображении формы.Мой VB.NET немного заржавел, но я приложу все усилия:
Сначала добавьте это как локальную переменную:
Private ShowLock As New ManualResetEvent(False);
Затем добавьте обработчик для HandleCreated
событие в frmSplash
, и в этом обработчике:
Public Sub Form_HandleCreated(...)
ShowLock.Set
End Sub
Затем в вашем методе ShowForm подождите, пока этот парень не установится:
Public Sub Show()
ShowLock.WaitOne
If frmSplash.InvokeRequired Then
If frmSplash.IsHandleCreated = True Then
appContext.MainForm.Invoke(ShowDelegate)
End If
End If
End Sub
Таким образом, вы уверены, чтодескриптор формы был создан до того, как первый поток попытается показать его (или сделать что-нибудь еще).
Наконец, защитите эти методы SetXXX
(делайте это для всего, что касается формы и может быть вызвано изСкрипт):
Public Sub SetDisplayText1(ByVal msg As String)
If frmSplash.InvokeRequired Then
Dim d As New SetDisplayText1Delegate(AddressOf SetDisplayText1)
frmSplash.Invoke(d, New Object() {[msg]})
Else
frmSplash.Label1.Text = msg
frmSplash.Label1.Refresh()
End If
End Sub
РЕДАКТИРОВАТЬ: Попробуйте это - я взял ваш код сверху и немного переработал его.
Private ShowLock As New ManualResetEvent(False)
Private WithEvents appContext As ApplicationContext
Private frmSplash As frmProgress
Private Delegate Sub FormDelegate()
Private Delegate Sub DisplayDelegate(ByVal msg As String)
Private Delegate Sub FormSettings(ByVal val As Boolean)
Private ShowDelegate As FormDelegate
Private HideDelegate As FormDelegate
Private UnLdDelegate As FormDelegate
Public Sub New()
MyBase.New()
frmSplash = New frmProgress
AddHandler frmSplash.HandleCreated, AddressOf frm_HandleCreated
Dim t As Thread
appContext = New ApplicationContext(frmSplash)
t = New Thread(AddressOf StartMessageLoop)
t.IsBackground = True
t.SetApartmentState(ApartmentState.STA)
t.Start()
End Sub
Public Sub SetDisplayText1(ByVal msg As String)
ShowLock.WaitOne()
If frmSplash.InvokeRequired Then
Dim d As New DisplayDelegate(AddressOf SetDisplayText1)
frmSplash.Invoke(d, New Object() {[msg]})
Else
frmSplash.Label1.Text = msg
frmSplash.Label1.Refresh()
End If
End Sub
Public Sub SetDisplayText2(ByVal msg As String)
ShowLock.WaitOne()
If frmSplash.InvokeRequired Then
Dim d As New DisplayDelegate(AddressOf SetDisplayText2)
frmSplash.Invoke(d, New Object() {[msg]})
Else
frmSplash.Label2.Text = msg
frmSplash.Label2.Refresh()
End If
End Sub
Public Sub SetTitle(ByVal msg As String)
ShowLock.WaitOne()
If frmSplash.InvokeRequired Then
Dim d As New DisplayDelegate(AddressOf SetTitle)
frmSplash.Invoke(d, New Object() {[msg]})
Else
frmSplash.Text = msg
End If
End Sub
Public WriteOnly Property AlwaysOnTop() As Boolean
Set(ByVal value As Boolean)
SetTop(value)
End Set
End Property
Public Sub Show()
ShowLock.WaitOne()
If frmSplash.InvokeRequired Then
If frmSplash.IsHandleCreated = True Then
ShowDelegate = New FormDelegate(AddressOf Show)
appContext.MainForm.Invoke(ShowDelegate)
End If
Else
frmSplash.Show()
End If
End Sub
Public Sub SetTop(ByVal val As Boolean)
ShowLock.WaitOne()
If frmSplash.InvokeRequired Then
Dim d As New DisplayDelegate(AddressOf SetTop)
frmSplash.Invoke(d, New Object() {[val]})
Else
frmSplash.TopMost = val
frmSplash.TopLevel = val
End If
End Sub
Public Sub Hide()
ShowLock.WaitOne()
If frmSplash.InvokeRequired Then
If frmSplash.IsHandleCreated Then
HideDelegate = New FormDelegate(AddressOf Hide)
appContext.MainForm.Invoke(HideDelegate)
End If
Else
frmSplash.Hide()
End If
End Sub
Public Sub Unload()
ShowLock.WaitOne()
If frmSplash.InvokeRequired Then
If frmSplash.IsHandleCreated Then
UnLdDelegate = New FormDelegate(AddressOf Unload)
appContext.MainForm.Invoke(UnLdDelegate)
End If
Else
frmSplash.Close()
End If
End Sub
Private Sub StartMessageLoop()
Application.Run(appContext)
End Sub
Private Sub ac_ThreadExit(ByVal sender As Object, ByVal e As System.EventArgs) Handles appContext.ThreadExit
appContext.MainForm.Dispose()
appContext.MainForm = Nothing
appContext.Dispose()
appContext = Nothing
frmSplash.Dispose()
frmSplash = Nothing
End Sub
Protected Overrides Sub Finalize()
MyBase.Finalize()
End Sub
Public Sub frm_HandleCreated()
ShowLock.Set()
End Sub