Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 跨线程静态方法调用_C#_Multithreading_Winforms - Fatal编程技术网

C# 跨线程静态方法调用

C# 跨线程静态方法调用,c#,multithreading,winforms,C#,Multithreading,Winforms,这是一个简单的问题,我已经找到了几个关于这个主题的答案,但即使两天后,我仍然没有找到适合这个场景的问题,所以我希望有人能帮我解决这个问题。 这是在主线程上调用的方法,不幸的是,它必须是静态的 public static class RichTextBoxExtensions { public static void AppendText(this RichTextBox box, string text, Color color) { box.SelectionS

这是一个简单的问题,我已经找到了几个关于这个主题的答案,但即使两天后,我仍然没有找到适合这个场景的问题,所以我希望有人能帮我解决这个问题。 这是在主线程上调用的方法,不幸的是,它必须是静态的

public static class RichTextBoxExtensions
{
    public static void AppendText(this RichTextBox box, string text, Color color)
    {
        box.SelectionStart = box.TextLength;
        box.SelectionLength = 0;
        box.SelectionColor = color;
        box.AppendText(text);
        box.SelectionColor = box.ForeColor;
    }
}
在另一条线上

public override void Write(string value)
        {
            //this.console.Invoke(new Action<String, Color>(this.console.AppendText), new Object { value, Color.White });
            //WindowsFormsSynchronizationContext.Current.Post(_ => this.console.AppendText(value, Color.White), new Object[] { value, Color.White });
            this.console.AppendText(value, Color.White);
        }
公共重写无效写入(字符串值)
{
//Invoke(新操作(this.console.AppendText),新对象{value,Color.White});
//WindowsFormsSynchronizationContext.Current.Post(=>this.console.AppendText(value,Color.White),新对象[]{value,Color.White});
this.console.AppendText(值,颜色,白色);
}
我尝试了Invoke和SynchronizationContext的实现,但无法使其正常工作,我可能使用了错误的实现,不是吗


声明方法的方式是阻止我使用我发现的任何解决方案的原因。

根据您展示的代码示例进行猜测,可能是您误解了对
静态方法的调用是如何工作的。或者可能是因为
静态方法是一种扩展方法

特别是,请理解扩展方法实际上是什么:它实际上只是一个普通的旧静态方法,编译器允许您使用语法调用它,使它看起来像是在调用实例方法。但是方法调用实际上只是一个静态方法调用,因此需要为方法提供所有参数

如果我猜对了,那么您可以通过将代码更改为如下所示的方式使其正常工作:

public override void Write(string value)
{
    this.console.Invoke(
        (Action<RichTextBox, string, Color>)RichTextBoxExtensions.AppendText,
        new object[] { this.console, value, Color.White });
}
换句话说,与其直接调用
AppendText()
扩展方法,不如调用一个匿名方法,该方法本身使用常用的扩展方法(即类似实例的语法)调用
AppendText()
方法

这样,编译器将解析匿名方法主体中类似实例的语法。被调用的方法实际上是一个更简单、无参数的匿名方法,因此获得正确的参数传递完全没有问题。:)

我明白了! 在主线程上,我有:

myHost = new Host(this, Console); //my custom PowerShell implementation
myHost = AddCommand("Write-Host"); //cmdlet to execute
myHost.Run(); // run the Command
调用Run()生成一个子线程,然后尝试写回主线程上的文本框。这是我第一次遇到“非法线程操作错误”的地方。 快速的google搜索揭示了几种使调用线程安全的方法,但是这个调用不会终止,也不会抛出任何错误。 这是因为主线程正在等待Run()调用返回,因此无法响应来自子线程的调用。
解决方案是移动管路();调用一个分离线程,使主线程保持活动状态,然后一切按预期工作。

。。。有什么问题吗?错误消息?Winforms或WPF?请比“无法使其正常工作”和“阻止我使用我发现有效的任何解决方案”更具体一些。请提供清楚的说明,清楚地显示您尝试了什么,以及清楚、准确地描述该代码的功能以及它与您希望它执行的功能的不同之处。问题是否存在于
静态方面或方法声明中是值得怀疑的,但是如果没有一个好问题,就很难帮助您。对不起,这是WinForms。Alex的答案比我尝试的要准确,但它只会导致一个循环,请参阅对该答案的评论我会用略读的完整代码更新问题,希望能有所帮助,现在我想这可能是因为嵌套类。我喜欢这样一个事实,即您建议将
调用
放在调用者中,而不是放在扩展方法中,与其他实例方法的实现保持一致。看起来不错,但这两个调用在静态方法中都没有达到断点…@VikFreeze:如果没有它,将可靠地再现问题,即使不是不可能,也很难确定问题是什么。请查看我在这里提供的链接中的信息,以了解需要什么样的代码示例。根据到目前为止您提供的信息,我所能说的是,如果从未调用static
AppendText()
方法,UI线程可能实际上在等待其他东西时被阻塞,从而阻止跨线程调用的完成。@PeterDuniho:好的,我添加了一种方法来复制这个问题,您可以更改
myHost.AddCommand(“写入主机”)
to
myHost.AddCommand(“dir”)在Form1_Load中,查看它是否与同步调用一起工作。谢谢你的帮助@VikFreeze:请重新阅读我提供的链接,以便您理解好的、最少的、完整的代码示例的含义。您提供的代码既不最少也不完整。
myHost = new Host(this, Console); //my custom PowerShell implementation
myHost = AddCommand("Write-Host"); //cmdlet to execute
myHost.Run(); // run the Command