类型安全Control.Invoke C#

编程入门 行业动态 更新时间:2024-10-26 11:12:48
本文介绍了类型安全Control.Invoke C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用C#编写一个包含2个线程的软件

I am programming a software in C# at work that contains 2 Threads

  • 控制窗体(Windows窗体)并与用户连接的线程.
  • 一个在后台检查在线数据的线程.
  • 当在线数据不规则时,我需要第二个线程在表格上打印消息.

    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#

    本文发布于:2023-11-13 09:26:54,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1584003.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:类型   Control   Invoke

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!