我目前正在开发一个必须处理多个线程的程序。当我启动程序时,我运行多个线程(我的示例仅限于一个)。我必须在一个TextBox中显示它们的状态。我选择了下一个解决方案。这种方式是对的吗?还有其他模式吗?观察者也许?我无法在网上找到一个好方法。
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;
}
}
}
答案 0 :(得分:3)
对我来说看起来很好。实际上你是使用观察者模式。这只是c#的漂亮事件语法,它消除了界面并减少了样板。
然而,那里存在大量冗余代码和其他可读性问题。
this
或this.textBox1
等内容时,this.Invoke(...)
限定符是多余的。private
或public
等可见性。new Thread(myThread.MyJob)
或myThread.Changed += myThread_Changed
。ChangedCallback
)。然后myThread_Changed方法可以接受一个int作为单个参数,允许您删除大量冗余类型。像这样:
JobEventHandler tmp = Changed;
if (tmp != null) tmp(this, e);
答案 1 :(得分:3)
您的代码不是很好。
Timer
?#
public partial class Form1
{
delegate void ChangedCallback(object sender, JobEventArgs e);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MyThread myThread = new MyThread();
myThread.Changed += myThread_Changed;
myThread.Start();
}
void myThread_Changed(object sender, JobEventArgs e)
{
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
{
private Thread _thread;
public MyThread()
{
_thread = new Thread(WorkerFunc);
}
public void Start()
{
_thread.Start();
}
// use the = {} pattern since you are using multithreading.
public event JobEventHandler Changed = {};
protected virtual void OnChanged(JobEventArgs e)
{
Changed(this, e);
}
private void WorkerFunc()
{
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(1000);
JobEventArgs e = new JobEventArgs(i);
OnChanged(e);
}
}
// A delegate type for hooking up change notifications.
public delegate void JobEventHandler(object sender, JobEventArgs e);