13

フォーム用の 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);
    }
}
4

4 に答える 4

24

このような

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それは理にかなっているので、クラスを不変にする自由を取りました。また、命名規則を部分的に修正し、必要に応じて簡略化し、修正しました。

于 2012-08-21T13:20:07.760 に答える
4

EventArgs を継承して新しいクラスを作成する必要があります。

于 2012-08-21T13:02:58.777 に答える
3

の独自のバージョンを作成します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;
    });
}
于 2012-08-21T13:07:26.010 に答える
1

一般に、プロパティを継承EventArgsして追加しstring、イベントを typeEventHandler<YourEventArgs>にする必要がありますが、これはBackgroundWorker.

サンプルはこちら: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

そしてここ: C#backgroundWorkerは文字列を報告しますか?

于 2012-08-21T13:05:46.413 に答える