1

私はC#を初めて使用し、スレッドからGUIフォームスレッドにイベントを渡す方法を理解するのに苦労しています。どんな助けでもいただければ幸いです。私が見つけたすべての例は非常に複雑です。御馳走からGUIまでの1つのイベントから始めて、GUIに何か(今は何でも)してもらいたいだけです。

namespace testEvents
{
public delegate void StuffHappenedDel( MessageEventArgs e);

public partial class Form1 : Form
{


    workerThread thread;
    int j = 0;
    public Form1()
    {
        InitializeComponent();
        thread = new workerThread();
        thread.Start();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        thread.Stop();
    }



    private void StuffHappenedDel(Object seder, EventArgs e)
    {
        j++;
    }


}

public class workerThread
{
    Thread worker;
    private bool _quit = false;

    /*  I don't think this next line is correct*/
    public event StuffHappenedDel StuffHappened;


    protected virtual void OnStuffHappened(MessageEventArgs e)
    {
        if (StuffHappened != null)
            StuffHappened( e);
    }


    public void Start()
    {
        ThreadStart start = new ThreadStart(Run);
        worker = new Thread(start);
        worker.Start();
    }

    private void Run()
    {
        int i = 0;
        while (!_quit)
        {
            Thread.Sleep(1000);
            i++;
            OnStuffHappened(new MessageEventArgs(false, "it worked!"));
            Console.WriteLine(string.Format("Slept {0} seconds.",i));
        }
        Console.WriteLine("Thread exiting");
    }
}


public class MessageEventArgs : EventArgs
{
    public MessageEventArgs(bool Error, string message)
    {
        IsError = Error;
        Message = message;
    }

    public bool IsError { get; set; }
    public string Message { get; set; }
}

}

4

3 に答える 3

1

このカスタムスレッドシステムを使用する必要がありますか、それともBackgroundWorkersを使用できますか?BackgroundWorkerを作成したスレッドで発生BackgroundWorkersするイベントがあります。ProgressChanged

または、UIスレッドからバックグラウンドイベントにハンドラーをアタッチした場合でも、作業はバックグラウンドスレッドで実行されます。

thread.StuffHappenedDel += new EventHandler<MessageEventArgs>(StuffHappenedDel);

したがって、データをUIスレッドにマーシャリングする必要があります。1つの方法は、を使用することBeingInvokeです。

private void StuffHappenedDel(object sender, MessageEventArgs e)
{
    this.myControl.BeginInvoke( new Action(
     () => 
     {
           //UI thread work (likely anything that affects UI. Heavy      
          //processing can continue on the bg thread outside this code block
     }));
}

また、if (myControl.InvokeRequired)特定のコントロールを変更するときにデータをマーシャリングする必要があるかどうかを確認するために使用できます。

  if (this.InvokeRequired)
  {
       this.Invoke((Action)(() =>
       {
           //UI thread stuff
       }
       ));
  }

明確にするために編集

作成したスレッドオブジェクトは、イベントハンドラーをイベントにアタッチする必要がありますStuffHappenedDel。これを行うには、次のようなものを使用します

thread.StuffHappenedDel += new EventHandler<MessageEventArgs>(StuffHappenedDel);

電話をかける前にthread.Start()。現在、このハンドラーは呼び出されます

private void StuffHappenedDel(Object seder, MessageEventArgs e)
{
    j++;
}

イベントが発生するたびに。

UI要素に変更を加える場合は、Invoke上記の方法を使用する必要があります。

于 2013-01-02T17:38:59.663 に答える