我在这方面有点新手,但我试图让黑白棋游戏上的 UI 运行在与移动选择部分不同的线程上,但我在单击按钮时调用线程时遇到了一些问题
private void playerMoveOKButton_Click(object sender, EventArgs e)
{
ReversiT.Invoke();
}
public void ReversiT() {...}
我在这方面有点新手,但我试图让黑白棋游戏上的 UI 运行在与移动选择部分不同的线程上,但我在单击按钮时调用线程时遇到了一些问题
private void playerMoveOKButton_Click(object sender, EventArgs e)
{
ReversiT.Invoke();
}
public void ReversiT() {...}
如果您尝试创建一个新线程,您可以执行以下操作:
Thread thread = new Thread(ReversiT);
thread.Start();
不过, Invoke用于不同的目的。它用于在特定线程上运行方法(例如,如果您在单独的线程上运行一段代码但想要进行 UI 更改,您将需要使用 Invoke 在 UI 线程上进行这些更改)
使用以下
this.Invoke(ReversiT);
我会创建一个BackgroundWorker
来为我处理所有事情,设置它的DoWork
事件来调用你的 move 方法(确保你的 move 方法不接触 UI,或者如果必须,调用 UI 线程上的控件)。
我还设置了一个方法来更新 BackgroundWorkerRunWorkerCompleted
事件的 UI。
现在在上面的按钮单击事件上,调用 BGW 的RunWorkerAsync()
方法。
我认为您需要考虑一下您实际上正在努力实现的目标。在 UI 中的单独线程上运行代码是一种用于阻止 UI 挂起的技术。但是,有些任务必须在 UI 线程上发生,因此不能从另一个线程运行。
您需要打破逻辑,以便您可以确定哪些部分需要在 UI 线程上运行(与 UI 上的控件交互的任何内容)以及可以在单独线程上运行的任何内容。
您最终会得到如下代码(例如):
private void playerMoveOKButton_Click(object sender, EventArgs e)
{
//thread is merely used as an example
//you could also use a BackgroundWorker or a task
var thread = new Thread(NonUiLogic);
thread.Start();
}
private void NonUiLogic()
{
...
//execute logic that doesn't touch UI
...
BeginInvoke(ReversiT);
}
public void ReversiT() {...}
一旦你完成了这个练习,你可能会发现实际上在 UI 线程之外几乎没有什么可以发生的,所以你真的没有从使用线程中获得任何好处。