在C#中处理线程状态的模式 [英] Pattern to handle threads status in C#

查看:174
本文介绍了在C#中处理线程状态的模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个必须处理多个线程的程序。当我启动程序时,我运行多个线程(我的例子被限制为一个)。我必须在一个TextBox中显示他们的状态。我选择了下一个解决方案。这样做是正确的吗?还有其他模式吗?观察员也许?我找不到一个在网络上这样做的好方法。

 命名空间ThreadTest 
{
public partial class Form1:Form
{
//该委托启用异步调用来设置
// TextBox控件上的text属性。
delegate void ChangedCallback(object sender,JobEventArgs e);

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender,EventArgs e)
{
MyThread myThread = new MyThread();
myThread.Changed + = new MyThread.JobEventHandler(myThread_Changed);

//创建线程对象,通过ThreadStart代理传递Alpha.Beta方法
//。这不会启动线程。
线程oThread = new Thread(new ThreadStart(myThread.MyJob));

//启动线程
oThread.Start();
}

void myThread_Changed(object sender,JobEventArgs e)
{
// InvokeRequired需要将
//调用线程的线程ID与创建线程的线程ID。
//如果这些线程不同,它返回true。
if(this.textBox1.InvokeRequired)
{
ChangedCallback d = new ChangedCallback(myThread_Changed);
this.Invoke(d,new object [] {sender,e});
}
else
{
//显示我的线程状态
textBox1.Text + = e.Counter;
}
}
}

public class MyThread
{
//挂接更改通知的委托类型。
public delegate void JobEventHandler(object sender,JobEventArgs e);

//当列表的
//元素更改时,客户端可以使用该事件进行通知。
公共事件JobEventHandler已更改;

//调用已更改事件;每当列表更改时调用
protected virtual void OnChanged(JobEventArgs e)
{
if(Changed!= null)
更改(this,e);
}

public void MyJob()
{
for(int i = 0; i <1000; i ++)
{
Thread.sleep代码(1000);
JobEventArgs e = new JobEventArgs(i);
OnChanged(e);
}
}
}

public class JobEventArgs
{

public int Counter {get;组; }

public JobEventArgs(int i)
{
Counter = i;
}
}
}


解决方案

对我来说看起来不错实际上,您使用观察者模式 。这只是c#的很好的事件语法,消除了界面并减少了样板。



但是,有很多冗余代码和其他可读性问题。
$ b


  • 当指定memeber(例如 this.textBox1 c )时, / code>或 this.Invoke(...)

  • 尽量总是指定可见性,例如 private public 用于方法。

  • 组启用简写语法。例如: new Thread(myThread.MyJob) myThread.Changed + = myThread_Changed

  • 考虑使用简单的Action作为事件处理程序委托类型而不是自定义( ChangedCallback )。然后,myThread_Changed方法可以接受int作为单个参数,允许您删除大量的冗余类型。

  • 为了避免在检查null和调用之前发生事件的线程本地副本



像这样:

  JobEventHandler tmp =更改; 
if(tmp!= null)tmp(this,e);


I am currently developing a program that must handle multiple threads. When I start the program I run multiple threads (my example is limited to one). I have to display their status in a single TextBox. I opted for the next solution. Is this way is correct? Are there any other pattern? The Observer perhaps? I can't find a good way to do this on the web.

namespace ThreadTest
{
    public partial class Form1 : Form
    {
        // This delegate enables asynchronous calls for setting
        // the text property on a TextBox control.
        delegate void ChangedCallback(object sender, JobEventArgs e);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            MyThread myThread = new MyThread();
            myThread.Changed += new MyThread.JobEventHandler(myThread_Changed);

            // Create the thread object, passing in the Alpha.Beta method
            // via a ThreadStart delegate. This does not start the thread.
            Thread oThread = new Thread(new ThreadStart(myThread.MyJob));

            // Start the thread
            oThread.Start();
        }

        void myThread_Changed(object sender, JobEventArgs e)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.textBox1.InvokeRequired)
            {
                ChangedCallback d = new ChangedCallback(myThread_Changed);
                this.Invoke(d, new object[] { sender, e });
            }
            else
            {
                // Display the status of my thread
                textBox1.Text += e.Counter;
            }
        }
    }

    public class MyThread
    {
        // A delegate type for hooking up change notifications.
        public delegate void JobEventHandler(object sender, JobEventArgs e);

        // An event that clients can use to be notified whenever the
        // elements of the list change.
        public event JobEventHandler Changed;

        // Invoke the Changed event; called whenever list changes
        protected virtual void OnChanged(JobEventArgs e)
        {
            if (Changed != null)
                Changed(this, e);
        }

        public void MyJob()
        {
            for (int i = 0; i < 1000; i++)
            {
                Thread.Sleep(1000);
                JobEventArgs e = new JobEventArgs(i);
                OnChanged(e);
            }
        }
    }

    public class JobEventArgs
    {

        public int Counter { get; set; }

        public JobEventArgs(int i)
        {
            Counter = i;
        }
    }
} 

解决方案

It looks just fine to me. In fact you are using the observer pattern. It's just c#'s nice event syntax eliminating the interface and reducing boilerplate.

However, there is a lot of redundant code and other readability problems in there.

  • The this qualifier is redundant when specifying a memeber such as this.textBox1 or this.Invoke(...).
  • Try to always specify visibility such as private or public for methods.
  • A suitable delegate is created automatically around a method-group enabling a shorthand syntax. For example: new Thread(myThread.MyJob) or myThread.Changed += myThread_Changed.
  • Consider using simple Action as event handler delegate types instead of a custom (ChangedCallback). The myThread_Changed method can then just accept an int as single parameter allowing you to drop lots of redundant types.
  • To avoid problems make a thread-local copy of the event before checking for null and invoking.

Like this:

JobEventHandler tmp = Changed;
if (tmp != null) tmp(this, e);

这篇关于在C#中处理线程状态的模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆