フォーム用のGUIスレッドと、物事を計算する別のスレッドがあります。
フォームにはrichtTextBoxがあります。すべての文字列がテキストボックスに表示されるように、ワーカースレッドが文字列をフォームに渡すようにします。
ワーカースレッドで新しい文字列が生成されるたびにイベントを呼び出します。これで文字列が表示されます。しかし、文字列を渡す方法がわかりません!これは私がこれまでに試したことです:
///// Form1
private void btn_myClass_Click(object sender, EventArgs e)
{
myClass myObj = new myClass();
myObj.NewListEntry += myObj_NewListEntry;
Thread thrmyClass = new Thread(new ThreadStart(myObj.ThreadMethod));
thrmyClass.Start();
}
private void myObj_NewListEntry(Object objSender, EventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
// Here I want to add my string from the worker-thread to the textbox!
richTextBox1.Text += "TEXT"; // I want: richTextBox1.Text += myStringFromWorkerThread;
});
}
///// myClass (working thread...)
class myClass
{
public event EventHandler NewListEntry;
public void ThreadMethod()
{
DoSomething();
}
protected virtual void OnNewListEntry(EventArgs e)
{
EventHandler newListEntry = NewListEntry;
if (newListEntry != null)
{
newListEntry(this, e);
}
}
private void DoSomething()
{
///// Do some things and generate strings, such as "test"...
string test = "test";
// Here I want to pass the "test"-string! But how to do that??
OnNewListEntry(EventArgs.Empty); // I want: OnNewListEntry(test);
}
}
このような
public class NewListEntryEventArgs : EventArgs
{
private readonly string test;
public NewListEntryEventArgs(string test)
{
this.test = test;
}
public string Test
{
get { return this.test; }
}
}
次に、このようにクラスを宣言します
class MyClass
{
public delegate void NewListEntryEventHandler(
object sender,
NewListEntryEventArgs args);
public event NewListEntryEventHandler NewListEntry;
protected virtual void OnNewListEntry(string test)
{
if (NewListEntry != null)
{
NewListEntry(this, new NewListEntryEventArgs(test));
}
}
}
購読中のForm
private void btn_myClass_Click(object sender, EventArgs e)
{
MyClass myClass = new MyClass();
myClass.NewListEntry += NewListEntryEventHandler;
...
}
private void NewListEntryEventHandler(
object sender,
NewListEntryEventArgs e)
{
if (richTextBox1.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
this.NewListEntryEventHandler(sender, e);
});
return;
}
richTextBox1.Text += e.Test;
}
NewListEntryEventArgs
クラスを不変にする自由をとったのは、それが理にかなっているからです。また、命名規則を部分的に修正し、必要に応じて簡略化および修正しました。
EventArgsを継承して、新しいクラスを作成する必要があります。
独自のバージョンのEventArgs
を作成します。
このようにしてください:
public class MyEventArgs : EventArgs
{
public string MyEventString {get; set; }
public MyEventArgs(string myString)
{
this.MyEventString = myString;
}
}
次に、コードでEventArgs
をMyEventArgs
に置き換え、文字列を含むMyEventArgs
オブジェクトを作成します。
次に、MyEventArgs
インスタンス.MyEventString
を使用してアクセスできます。
したがって、次のようなことを行います。
///// myClass (working thread...)
class myClass
{
public event EventHandler NewListEntry;
public void ThreadMethod()
{
DoSomething();
}
protected virtual void OnNewListEntry(MyEventArgs e)
{
EventHandler newListEntry = NewListEntry;
if (newListEntry != null)
{
newListEntry(this, e);
}
}
private void DoSomething()
{
///// Do some things and generate strings, such as "test"...
string test = "test";
OnNewListEntry(new MyEventArgs(test));
}
}
そしてあなたの形で:
private void myObj_NewListEntry(Object objSender, MyEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate
{
// Here I want to add my string from the worker-thread to the textbox!
richTextBox1.Text += e.MyEventString;
});
}
一般に、EventArgs
を継承してstring
プロパティを追加してから、タイプEventHandler<YourEventArgs>
のイベントを作成する必要がありますが、これはBackgroundWorker
の典型的なケースです。 。
ここのサンプル: http://msdn.Microsoft.com/en-us/library/cc221403(v = vs.95).aspx
そしてここで: C#backgroundWorkerは文字列を報告しますか?