交叉线程静态方法调用

时间:2015-05-26 00:51:10

标签: c# multithreading winforms

这是一个简单的问题,我已经找到了几个关于这个主题的回答问题,但即使在2天后我仍然没有找到适合这种情况的东西,所以我希望有人可以帮助我。 这是调用主线程的方法,不幸的是它必须是静态的

Z = XY
X = ("ab")+
Y = "abc"

在另一个帖子上

// takes an input string and returns the length of match, -1 for failure
int Z(str) {
  int len1 = X(str);
  if (len1 >= 0) {
    int len2 = Y(str.substr(length));
    if (len2 >= 0) {
      return len1 + len2; // matches
    }
  }
  return -1; // doesn't match
}
int X(str) {
  // matches 1 or multiple "ab"
  int len = 0;
  while (str.startsWith("ab")) {
    len += 2;
    str = str.substr(2);
  }
  return len > 0 ? len : -1;
}
int Y(str) {
  // matches "abc" exactly
  return str.startsWith("abc") ? 3 : -1;
}

我尝试使用Invoke和SynchronizationContext进行实现,但无法使其正常工作,我可能错误地使用它们,不是吗?

该方法必须被宣布的方式是什么阻止我做出我认为适合我的任何解决方案。

2 个答案:

答案 0 :(得分:2)

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

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

如果我猜错了,那么您可以通过将其更改为以下内容来使代码正常工作:

public override void Write(string value)
{
    this.console.Invoke(
        (Action<RichTextBox, string, Color>)RichTextBoxExtensions.AppendText,
        new object[] { this.console, value, Color.White });
}

由于AppendText()方法实际上是static方法,因此您需要通过其声明的类(即RichTextBoxExtensions)明确提供方法引用。通过类似实例的语法调用扩展方法只有在编译时可以解析该调用语法时才有效,而这种情况并非如此。

请注意,如果您不介意在另一个匿名方法中包装方法调用,则可以稍微简化语法:

public override void Write(string value)
{
    this.console.Invoke(
        (MethodInvoker)(() => this.console.AppendText(value, Color.White)));
}

换句话说,不是直接调用AppendText()扩展方法,而是使用通常的扩展方法(即类似实例)语法调用一个本身调用AppendText()方法的匿名方法。

这样,编译器就会在匿名方法的主体中解析类似实例的语法。被调用的方法实际上是更简单,无参数的匿名方法,因此完全正确的参数传递没有任何麻烦。 :)

答案 1 :(得分:0)

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

myHost = new Host(this, Console); //my custom PowerShell implementation
myHost = AddCommand("Write-Host"); //cmdlet to execute
myHost.Run(); // run the Command

对Run()的调用会生成一个子线程,然后尝试写回主线程上的文本框。这是我第一次遇到“非法线程操作错误”的地方。 快速谷歌搜索揭示了几种使调用线程安全的方法,但这个调用永远不会终止,也不会抛出任何错误。 这是因为主线程正在等待Run()调用返回,因此无法对子线程的调用作出反应。 解决方案是移动Run();调用一个separete线程,以便主线程保持活动状态,然后一切都按预期工作。