【问题标题】:C#: String as parameter to event?C#:字符串作为事件的参数?
【发布时间】:2012-08-21 13:01:26
【问题描述】:

我的表单有一个 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);
    }
}

【问题讨论】:

  • 子类 EventArgs 并将您的字符串添加为属性。

标签: c# .net multithreading events event-handling


【解决方案1】:

这样

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 类不可变,因为这是有道理的。我还部分更正了您的命名约定,在方便的地方进行了简化和更正。

【讨论】:

  • 谢谢,但在 this.BeginInvoke(NewListEntryEventHandler, sender, e);跨度>
  • 我的错误,应该采用委托而不是方法组。我改进了我的代码。
  • OMG 事件是一个 PITA
【解决方案2】:

您需要通过继承 EventArgs 来创建一个新类。

【讨论】:

    【解决方案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;
        });
    }
    

    【讨论】:

    • 当我将 crawler.NewListEntry += crawler_NewListEntry; 添加到我的 Form1 时,我收到错误:没有与委托 System.EventHandler' 匹配的重载。 ??
    【解决方案4】:

    一般你需要继承EventArgs并添加一个string属性,然后让你的事件类型为EventHandler<YourEventArgs>,但这是BackgroundWorker的经典案例。

    这里的示例: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

    这里: C# backgroundWorker reports string?

    【讨论】:

      猜你喜欢
      • 2012-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多