【问题标题】:Control.Invoke delegates in CF 3.5CF 3.5 中的 Control.Invoke 委托
【发布时间】:2011-11-03 01:25:13
【问题描述】:

似乎每个人都注意到 CF 无法 Control.Invoke 除了 EventHandler 类型的委托。我发现很少有方法可以解决这个问题并通过棘手的事件和属性捕获参数,但它仅适用于某些对象/基元。

问题是当我尝试发送 Control 时,程序在执行时抛出异常:“Control.Invoke 必须用于与在单独线程上创建的控件交互”不管我检查 Control.IsInvokeRequired 并跟踪由处理程序通过 Invoke 方法...什么鬼,有片段:

    static class Program
{
    [MTAThread]
    static void Main()
    {
        Form1 frm = new Form1();
        frm.modifier = new CModifier(ref frm);
        Application.Run(frm);
    }
 }

class CModifier
{
    internal event EventHandler Modify;

    internal CModifier(ref Form1 _frm)
    { frm = _frm; }

    private Form1 frm;

    internal void Start()
    {
        Thread t = new Thread(new ThreadStart(TestMe));
        t.Start();
    }
    private void TestMe()
    {
        frm._current = new Label() { Text = "Try Me" };
        Modify(this, EventArgs.Empty);
    }

}

public partial class Form1 : Form
{
    internal Form1()
    {
        InitializeComponent();
    }

    internal CModifier modifier;
    internal Control _current;

    private void Form1_Load(object sender, EventArgs e)
    {
        modifier.Modify += new EventHandler(modifier_Modify);
        modifier.Start();
    }

    void modifier_Modify(object sender, EventArgs e)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new EventHandler(modifier_Modify));
        }
        this.panel1.Controls.Add(_current);
    }

}

我尝试了几乎所有可能的方式,但我总是得到相同的结果。

我做错了什么? ----> 有一个“返回;”调用后丢失。

无论如何,我的应用程序的实际错误(以上只是一个示例)在此过程中:

        internal void ManageControls(RSSDecisionMaking.InterfaceBehaviour _behaviour, Control _control)
    {
        if (this.InvokeRequired)
        {
            this.Invoke((Action)delegate { ManageControls(_behaviour, _control); });
            return;
        }
        switch (_behaviour)
        {
            case RSSDecisionMaking.InterfaceBehaviour.Display:
                this.pnDisplayContainer.Controls.Clear();
                this.pnDisplayContainer.Controls.Add(_control);
                break;
            case RSSDecisionMaking.InterfaceBehaviour.Command:
                this.pnDisplayContainer.Controls.Clear();
                this.pnDisplayContainer.Controls.Add(_control);
                this.pnDisplayContainer.Controls[0].Focus();
                break;
        }
    }

主要区别在于 Invoke 的东西,我从另一个线程发送一个 Control。

能告诉我它有什么不同吗?为什么这不起作用?

【问题讨论】:

    标签: c# compact-framework thread-safety


    【解决方案1】:

    问题很简单。您的 modifier_Modify 调用正确调用 Invoke,但随后它没有退出,它继续向下并在 if 块之后立即在线程上下文中调用 Controls.Add (实际上,如果 Exception 没有,Controls.Add 将被调用两次不会发生)。在 this.Invoke 调用之后,在 if 块内插入一个 return

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-24
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多