我想我曾经有过简单的问题:
Thread myThread = new Thread(MainProcessingThread);
myThread.IsBackground = true;
isThreadRunning = true;
myThread.Start();
和方法:
public void MainProcessingThread()
{
}
您可以看到上述方法不是静态的。这段代码以前都有用。但是我已经将方法的名称(不是formInstance.MainProcessingThread
)传递给上面的线程。我做错什么了吗?这是怎么回事?
ps MainProcessingThread
是主要表单的成员。我可以直接从该方法访问表单成员(实例)变量吗?
答案 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操作并获得异常。即使你保持合理的分离,它实际上也很容易 - 数据绑定也危险。