まず、処理クラスを拡張しないでくださいForm1
。これは、既存のフォームのメソッドにアクセスできるという幻想を与えていますが、それはあなたが思っていることをしていません。これを行うと、まったく新しいフォームが作成され、表示されなくなります。そのフォームにはすべてのインスタンスフィールドの独自のセットがあるため、メインフォームのコントロールにアクセスすることはありません。これが機能する(そして機能しない)としても、適切に設計されたソリューションではありません。
これを行う適切な方法は、実際にははるかに簡単です。他のクラスがそのメソッドから値を返すようにする必要があります。
public class PrintClass
{
public string DoWork()
{
Thread.Sleep(2000);//placeholder for real work.
return "Process Completed";
}
}
これで、メインフォームはそのメソッドを呼び出して、戻り値をテキストボックスに追加できます。
これを行うと、まったく別の問題が発生します。UIスレッドで作業を行うと、作業中にそのUIスレッドがブロックされ、フォームが再描画されたり、その他のイベントが処理されたりするのを防ぐことができます。バックグラウンドスレッドで作業を行ってから、UIスレッドにマーシャリングして、結果でUIを更新する必要があります。これを行うにはいくつかの方法がありますが、C#5.0を使用している場合は、使用await
するのがはるかに簡単です。
public class Form1 : Form
{
private void SomeEventHandler(object sender, EventArgs args)
{
string result = await Task.Run(()=>new PrintClass().DoWork());
TboxPrint.AppendText(result);
}
}
C#4.0ソリューションが必要な場合はContinueWith
、を使用できます。これは、多かれ少なかれ上記に変換されるものですが、構文はそれほどきれいではありません。
public class Form1 : Form
{
private void SomeEventHandler(object sender, EventArgs args)
{
Task.Factory.StartNew(()=>new PrintClass().DoWork())
.ContinueWith(t => TboxPrint.AppendText(t.Result)
, CancellationToken.None
, TaskContinuationOptions.None
, TaskScheduler.FromCurrentSynchronizationContext());
}
}