1

我正在用 c# 编写一个表单应用程序,我需要能够从任何线程更改富文本框的内容,我尝试使用委托InvokeRequired,但我所做的委托仍然给我一个跨线程调用错误,并且 InvokeRequired 使表单崩溃,而不会给出错误。我需要能够从任何线程执行的功能:

    public static void updateSub(int what)
    {
        subDisplay.subBox.Text = tb[what];
    }

我尝试使用的代表:

    public delegate void UpdateDelegateVoid(int what);
    static public UpdateDelegateVoid uSub = new UpdateDelegateVoid(updateSub);
    uSub(0);

我的 InvokeRequired 代码:

    public static void updateSub(int what)
    {
        if (subDisplay.subBox.InvokeRequired)
        {
            subDisplay.subBox.Invoke(new MethodInvoker(finish));
        }
        else
        {
            subDisplay.subBox.Text = tb[what];
        }
    }

我不太确定为什么上面的代码不起作用。谢谢!

4

3 回答 3

3

严格来说,当您检查InvokeRequired并找到它时true,您应该将调用编组到相同的方法。我不确定它是否能解决您的具体问题(我需要查看更多异常详细信息和代码),但这就是我的意思:

public static void updateSub(int what)
{
    if (subDisplay.subBox.InvokeRequired)
    {
        subDisplay.subBox.Invoke(new Action<int>(updateSub), what);
    }
    else
    {
        subDisplay.subBox.Text = tb[what];
    }
}

如果您遇到“奇怪的行为”,请检查该表单是否实际上是在主应用程序线程上创建的。在 WinForms 中,这不是强制的(就像在 WPF 中一样),因此创建表单的线程可能实际上不是应用程序的根线程。

于 2011-04-28T08:56:09.343 回答
2

我主要使用这个,它工作得很好。出于完全相同的目的是您的意图。

public void UpdateSub(string message)
{
    subDisplay.subBox.Invoke((Action)delegate {
        subDisplay.subBox.Text = message;
    });
}

希望它对您或其他人有所帮助!

于 2011-04-28T09:15:32.303 回答
1

试试这个——如果需要调用,你可以调用相同的方法。

public void UpdateSub(string message)
{
    if (!subDisplay.subBox.InvokeRequired)
    {
        subDisplay.subBox.Text = message;
    }
    else
    {
        var d = new UpdateFormText(UpdateSub);
        Invoke(d, new object[] { message });
    }
}

其中 UpdateFormText 是委托

public delegate void UpdateFormText(string message);
于 2011-04-28T08:56:34.233 回答