我在这方面有点新手,但我试图让黑白棋游戏上的 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 线程之外几乎没有什么可以发生的,所以你真的没有从使用线程中获得任何好处。