|
分類:[C#]
環境:VS2013、C#、Formアプリ、ライブラリ
やりたいこと:
ライブラリを利用する利用者側に、ライブラリ内でスレッドを生成していることを
できるだけ意識させず、スレッド内の情報を利用者側に提供したい。
現在、下記のソースのように、int型の変数を1つ返すイベントを定義し、
スレッド内からフォームへイベントを発生させています。
そのイベント内からtextBox1にアクセスするとエラーになるため、
Invokeを利用しています。
このInvokeを利用者側が実装しなくても利用できるようにしたいのですが、
それを考えている最中にそもそもどのような理屈で動作しているのかわからないくなってしまいました。
まだまだ小生の理解が足りていないと思っています。
そこで下記質問させてください。
質問1
1回目のClass1_Countは別スレッドから同期式(event)で呼び出しているので
別スレッド(work)で実行されている?
質問2
1回目のClass1_CountのCountEventArgs eは、別スレッド内で
newしているので別スレッドの持ち物?
質問3
eventをやめて非同期式でデリゲートを経由すれば、
Class1_CountはUIスレッドで実行される?
質問4
InvokeはメインスレッドでClass1_Countを実行するメソッド?
質問5
どのような実装が一般的なのでしょうか?
==下記ソースは問題なく動作しています==
using System.Threading;
namespace ClassLibrary1
{
public class CountEventArgs : EventArgs
{
public int eCount;
}
public class Class1
{
public delegate void CountEventHandler(object sender, CountEventArgs e);
public event CountEventHandler Count;
public void Start()
{
Thread t1 = new Thread(new ThreadStart(work));
t1.Start();
}
public void work()
{
int wCount = 100;
if (Count != null)
{
CountEventArgs e = new CountEventArgs();
e.eCount = wCount;
Count(this, e);
}
}
}
}
public partial class Form1 : Form
{
ClassLibrary1.Class1 c1;
private void button1_Click(object sender, EventArgs e)
{
c1 = new ClassLibrary1.Class1();
c1.Count += new ClassLibrary1.Class1.CountEventHandler(Class1_Count);
c1.Start();
}
public void Class1_Count(object sender, ClassLibrary1.CountEventArgs e)
{
if (this.InvokeRequired)
{
ClassLibrary1.Class1.CountEventHandler dlgt = new ClassLibrary1.Class1.CountEventHandler(Class1_Count);
this.Invoke(dlgt, new object[] { sender, e });
return;
}
textBox1.Text = e.eCount.ToString();
}
}
|