我正在使用C#编写一个包含2个线程的软件
I am programming a software in C# at work that contains 2 Threads
当在线数据不规则时,我需要第二个线程在表格上打印消息.
I need the second thread to print a massage on the form when the online data is irregular.
因为只有创建控件的线程才能更改它,所以我正在使用委托. 第二个线程通过Control.Invoke方法调用第一个线程来执行委托.
because only the thread that created the control can change it, I am using delegates. the second thread calls the first thread to execute a delegate by the Control.Invoke method.
示例:
public partial class Form1 : Form { public delegate void SafeCallDelegate(string text); public static SafeCallDelegate d; public Form1() { InitializeComponent(); d = new SafeCallDelegate(addText); } private static void addText(string text) { richTextBox1.Text += text + "\n"; } } static class Program { static Thread secondThread; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); secondThread = new Thread(SecondThreadFunc); secondThread.Start(); Application.Run(new Form1()); } static void SecondThreadFunc() { int counter = 0; do { if (Form.ActiveForm == null) continue; Form.ActiveForm.Invoke(Form1.d, new object[] { "SecondThreadFunc counter: " + counter.ToString() }); counter++; Thread.Sleep(1000); } while (true); } }我可以接受这种不太干净的解决方案,但是我的问题是这根本不是类型安全的.
I can live with this not very clean solution, but my problem is that this is not type-safe at all.
Control.Invoke函数接受一个对象数组,无论委托要求什么,这都可能导致运行时异常.
the Control.Invoke function takes an array of objects, regardless of what the delegate requires and this can result in a run-time exception.
有没有一种类型更安全并且可以解决我的问题的方法?
Is there a method to use that is more type-safe and can solve my problem?
谢谢.
推荐答案不是将参数传递给Invoke,而是将它们作为封闭变量.
Instead of passing the arguments to Invoke, pass them as a closured variable within the delegate.
所以,代替这个:
Form.ActiveForm.Invoke(Form1.d, new object[] { "SecondThreadFunc counter: " + counter.ToString() });写这个:
Form.ActiveForm.Invoke ( new Action ( () => Form1.d("SecondThreadFunc counter: " + counter.ToString()) ) );这避免了将参数传递给Invoke的问题,并消除了类型安全性问题.
This avoids the problem of passing arguments to Invoke and eliminates the type-safety issue.
如果您觉得这有些罗y,还可以定义一个简单的辅助程序扩展方法:
If that seems a little wordy to you, you can also define a simple helper extension method:
static class Helpers { static public void MyInvoke(this Control control, Action action) { if (control.InvokeRequired) { control.Invoke(action); } else { action(); } } }现在您所要写的主要形式是:
Now all you have to write in your main form is this:
this.MyInvoke( () => addText("SecondThreadFunc counter: " + counter.ToString()));现在,您可以摆脱所有SafeCallDelegate的内容,只在需要时传递所需的任何lambda.
You can now get rid of all that SafeCallDelegate stuff and just pass whatever lambda you want when you need it.
更多推荐
类型安全Control.Invoke C#
发布评论