新线程签名(静态与非静态方法)

时间:2015-05-14 08:33:57

标签: c# multithreading

我想我曾经有过简单的问题:

Thread myThread = new Thread(MainProcessingThread);
myThread.IsBackground = true;
isThreadRunning = true;
myThread.Start();

和方法:

 public void MainProcessingThread()
 {
 }

您可以看到上述方法不是静态的。这段代码以前都有用。但是我已经将方法的名称(不是formInstance.MainProcessingThread)传递给上面的线程。我做错什么了吗?这是怎么回事?

ps MainProcessingThread是主要表单的成员。我可以直接从该方法访问表单成员(实例)变量吗?

2 个答案:

答案 0 :(得分:3)

鉴于MainProcessingThread是实例方法,以下行

Thread myThread = new Thread(MainProcessingThread);

的简写
Thread myThread = new Thread(new ThreadStart(this.MainProcessingThread));

所以,你确实在使用这个对象。此指针被视为隐式引用。为了能够这样做,您应该在另一个实例方法/属性中调用它,否则您将无法访问this引用。例如,如果您在静态方法中执行此操作,则会收到编译错误,因为您无法访问this关键字。

另一方面,如果该方法恰好是静态方法,则会将其编译为

Thread myThread = new Thread(new ThreadStart(ClassName.MainProcessingThread));

答案 1 :(得分:0)

.NET委托与它们关联Target - 这对应于由这些委托包装的非静态方法中使用的this引用。

在您的情况下,您使用的是ThreadStart代表。如果您明确创建new ThreadStart(formInstance.YourMethodName,则可以查询其Target属性,并查看它是否引用formInstance

调用委托时,此Target值(如果有)作为底层方法的第一个参数传递 - C#表示为this引用。

为了更好地理解这一点,IL(.NET的中间语言)实际上 并不像this那样。你的方法是实例方法还是静态方法并不是太在乎(注意.NET类型信息确实有这种区别,但不是IL本身)。相反,C#的this作为第一个参数传递给任何实例方法(包括属性访问器等) - 这有点简化,因为你可以有不同的调用约定,但它对于常见的情况来说已经足够了。因此,虽然您无法在C#中使用任何this调用实例方法,但在IL中它是相当微不足道的。代理人的Invoke方法可以简单地将Target值作为第一个参数传递,并“模拟”C#this的工作方式。

至于良好做法,请避免从其他线程访问GUI元素。这很容易导致意外的跨线程GUI操作并获得异常。即使你保持合理的分离,它实际上也很容易 - 数据绑定危险。