WinFormのスレッドの親をGUIスレッドに戻す方法を見つけようとしています。現在、別のスレッドからフォームを作成する必要がありますが、それを参照しているメインフォームからアクセスできなくなります。
ここに私が持っているもののサンプル
public partial class MainForm : Form
{
// local instance of the sub form
private ViewForm SubForm { get; set;} = null;
public MainForm()
{
InitializeComponent();
Task.Run(() =>
{
// set the sub form
SubForm = new ViewForm();
}
// call the rest of the initialization of main form
InitializeCustomControls();
}
private void OpenViewWindow_Click(object sender, EventArgs e)
{
// if the window is instanciated
if (SubForm != null)
{
SubForm.Show();
}
}
}
ViewForm
ウィンドウではありませんForm
オブジェクト。これはカスタムのサードパーティウィンドウです。テーマと混合された多くのコントロールとテンプレートがあります。新しい空のコンストラクターへの唯一の呼び出しには最大7秒かかる可能性があるため、メインウィンドウの読み込みを続行しながら、別のスレッドでコンストラクターを作成する必要があります。
現在.Show()
、スレッド作成の制限のために常に失敗するものを除いて、ウィンドウ内の任意のメソッドを呼び出すことができます。スレッドを無限に実行するスレッドとして作成することは避けたいと思います。このスレッドは、ウィンドウを表示および非表示にするタイミングを指示するオブジェクトを待機して読み取ります。
これは.Show()
エラーです:
Cross-thread operation not valid: Control 'ViewForm' accessed from a thread other than the thread it was created on.
代わりに次のことを試しましたが、それでもインターフェイスがフリーズします:
Task.Run(() =>
{
// set the sub form
this.Invoke(new MethodInvoker(delegate
{
SubForm = new ViewForm();
}));
}
私が欲しいのは、火のようなもので、GUIオブジェクトのインスタンス化を忘れます。
を使用したソリューションはBackGroundWorker
次のとおりです。
public partial class MainForm : Form
{
// local instance of the sub form
private ViewForm SubForm { get; set;} = null;
public MainForm()
{
InitializeComponent();
backGroundWorker1.RunWorkerAsync();
InitializeCustomControls();
}
private void OpenViewWindow_Click(object sender, EventArgs e)
{
// if the window is instanciated
if (SubForm != null)
{
SubForm.Show();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
SubForm = new ViewForm();
}
}
MainForm
サンプルのSubView
フォームとThreading.Sleep(10000)
コンストラクターにが付いたフォームの2つのフォームの作成をテストしました。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加