C# 在C中从其他线程调用函数#

C# 在C中从其他线程调用函数#,c#,C#,我有一个带有函数XYZ()的GUI主线程来处理GUI。 在另一个线程中,若我从主GUI的句柄调用XYZ(),它将显示错误 “跨线程操作无效:从创建控件“Button00”的线程以外的线程访问该控件。” 我应该如何解决这个问题?我想我需要向GUI线程发送一条消息来执行XYZ功能。请帮帮我 谢谢 Ankata您收到此错误消息的原因是您试图从不同于主线程的线程更新GUI控件,这是不可能的。GUI控件应始终在用于创建它们的同一线程上进行修改 您可以使用if来封送对主线程的调用。这是一个例子 但最简单的解

我有一个带有函数XYZ()的GUI主线程来处理GUI。 在另一个线程中,若我从主GUI的句柄调用XYZ(),它将显示错误 “跨线程操作无效:从创建控件“Button00”的线程以外的线程访问该控件。”

我应该如何解决这个问题?我想我需要向GUI线程发送一条消息来执行XYZ功能。请帮帮我

谢谢


Ankata

您收到此错误消息的原因是您试图从不同于主线程的线程更新GUI控件,这是不可能的。GUI控件应始终在用于创建它们的同一线程上进行修改

您可以使用if来封送对主线程的调用。这是一个例子

但最简单的解决方案可能是简单地使用,因为这样您就不再需要手动封送对GUI线程的调用。这是自动完成的:

var worker = new BackgroundWorker();
worker.DoWork += (sender, e) =>
{
    // call the XYZ function
    e.Result = XYZ();
};
worker.RunWorkerCompleted += (sender, e) =>
{
    // use the result of the XYZ function:
    var result = e.Result;
    // Here you can safely manipulate the GUI controls
};
worker.RunWorkerAsync();
一般来说,C#中的GUI只能从创建它的同一线程更新 如果它不是同一个线程,则invokererequired的值为true,否则为false, 如果为真,则再次调用相同的方法,但从相同的线程创建GUI

您应该这样使用它:

 delegate void valueDelegate(string value);

    private void SetValue(string value)
    {   
        if (someControl.InvokeRequired)
        {
            someControl.Invoke(new valueDelegate(SetValue),value);
        }
        else
        {
            someControl.Text = value;
        }
    }
请尝试此项以获取更多信息


在我的代码中:函数XYZ是做一些事情并处理一些GUI控件,并放置在主窗体类中。我尝试将您的帮助代码添加到其他thead中,以mainForm.XYZ()的形式调用XYZ函数,但这是相同的错误?因此您必须将更新GUI控件的过程拆分为两个单独的函数。这样,您将使用第一个函数在后台工作程序中执行昂贵的处理,当它返回结果时,您将调用第二个函数来更新GUI。如果不拆分它们,则无法在其他线程上运行,因为正如我的回答中所述,GUI控件只能在主线程上更新。但是,处理和更新GUI的代码非常复杂。我尝试将帮助代码添加到其他线程中,以mainForm.XYZ()的形式调用XYZ函数,但这是同样的错误?根据原始问题的措辞,我怀疑OP实际上是在XYZ()方法中更新UI。如果是这种情况,从BackgroundWorker调用它将无法解决问题,因为仍然会存在跨线程问题。因为在更新许多控件之前和之后都有很多进程。所以我不能使用委托方法。你知道如何将消息发送到另一个线程并由它自己处理吗?我不明白为什么不能使用委托,你确定你理解上面的代码吗?这段代码只是检查您是否在创建控件的线程中,如果不是,它将从rigth线程调用相同的方法,这对您来说是不可见的,因此委托的声明是关键问题。。