类型安全Control.Invoke C# [英] type-safe Control.Invoke C#

查看:118
本文介绍了类型安全Control.Invoke C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

  1. 控制窗体(Windows窗体)并与用户连接的线程.
  2. 一个在后台检查在线数据的线程.

当在线数据不规则时,我需要第二个线程在表格上打印消息.

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#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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