問題を明確に言い換えるには、独自のプログラム内でそれを使用するクライアントにビジュアルコンポーネントを提供する必要があります。クライアントのプログラムは、ユーザーの制御の及ばないところで、そのメイン(つまり:UI)スレッドを拘束し、クライアントのプログラムがフリーズしている間、ビジュアルコンポーネントを引き続き機能させる必要があります。
ここで明確にしましょう-クライアントのプログラムがフリーズしているという事実は彼らの問題であり、それは彼らのアプリケーションコードの欠陥の直接の結果です。以下に続くのはハックであり、誰も使用してはならないひどいものです。したがって、次のことを行うことはできますが、それが推奨される解決策と見なされることはほとんどありません。それはすべてのベストプラクティスに直面して飛ぶ。
そうは言っても、メインUIスレッドの横で実行を継続できる2番目のアプリケーションコンテキストと新しいメッセージループを作成する必要があります。このようなクラスは機能します:
Imports System.Threading
Public Class SecondUIClass
Private appCtx As ApplicationContext
Private formStep As Form
Private trd As Thread
Private pgBar As ProgressBar
Delegate Sub dlgStepIt()
Public Sub New()
trd = New Thread(AddressOf NewUIThread)
trd.SetApartmentState(ApartmentState.STA)
trd.IsBackground = True
trd.Start()
End Sub
Private Sub NewUIThread()
formStep = New Form()
pgBar = New ProgressBar()
formStep.Controls.Add(pgBar)
appCtx = New ApplicationContext(formStep)
Application.Run(appCtx)
End Sub
Public Sub StepTheBar()
formStep.Invoke(New dlgStepIt(AddressOf tStepIt))
End Sub
Private Sub tStepIt()
pgBar.PerformStep()
End Sub
End Class
基本的に、上記のクラスで行っているのは、新しいSTAスレッド内に新しいアプリケーションコンテキストを作成することです(そのスレッドにメッセージループを与えます)。そのコンテキストには、メインUIスレッドとは別に動作し続けることができるメインフォーム(スレッドの所有権とメッセージ処理の責任を与える)が含まれています。これは、プログラム内にプログラムを配置するのとよく似ています。2つのUIスレッドには、それぞれが相互に排他的なコントロールのセットがあります。
新しいUIスレッド(またはそのフォーム)が所有するコントロールのいずれかと対話する呼び出しは、Control.Invoke
新しいUIスレッドが対話を行うものであることを確認するために、プライマリUIスレッド(または他のスレッド)からマーシャリングする必要があります。ここでも使用できBeginInvoke
ます。
このクラスにはクリーンアップコードや安全性のチェックなどがなく(警告)、正常に終了するかどうかさえわかりません。そのタスクはあなたに任せます。これは、開始する方法を示しています。メインフォームでは、次のようなことを行います。
Public Class Form1
Private pgClass As New SecondUIClass
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
For i = 1 To 10
System.Threading.Thread.Sleep(1000)
pgClass.StepTheBar()
Next
End Sub
End Class
上記のアプリケーションを実行すると、Form1
によって作成された2番目のフォームと同様に作成されpgClass
ます。をクリックするとButton1
、ループを通過している間Form1がロックされますが、2番目のフォームは引き続き有効で応答性が高く、が呼び出されるForm1
たびに進行状況バーが更新されます。Form1
.StepTheBar()
この場合の最善の解決策は、実際には、「クライアント」に適切なプログラミング方法を学習させ、そもそもこの難問にとらわれないようにすることです。それが完全に不可能であり、あなたが彼らのために彼らの貧弱なコードにもかかわらず生き続けるコンポーネントを作成しなければならない場合、上記のアプローチはおそらくあなたの唯一の頼みの綱です。