gpt4 book ai didi

C# 如何从另一个线程关闭主 UI 线程上的窗口窗体

转载 作者:行者123 更新时间:2023-11-30 19:02:51 25 4
gpt4 key购买 nike

我正在创建 WPF MVVM 应用程序。我有一个很长的过程,我想在另一个线程中运行,同时向用户显示忙碌指示器。我遇到的问题如下:

BusyIndi​​cator 控件的 IsBusy 属性绑定(bind)到实现 INotifyPropertyChanged 接口(interface)的 View 模型的 IsBusy 公共(public)属性。如果我使用 Join 运行下面的代码,那么用户界面不会显示忙碌指示器,因为主 UI 线程正在等待线程“t”完成。如果我删除连接,则托管 WPF 的 Windows 窗体会过早关闭。我知道跨线程访问 Windows Forms 是一个很大的禁忌,但因为我想做的就是关闭 Form 我认为最简单的解决方案是将 _hostForm.Close() 移动到“DoLongProcess”方法的末尾。当然,如果我这样做,我会得到一个跨线程异常。您能否建议在这种情况下采取的最佳方法?

<extToolkit:BusyIndicator IsBusy="{Binding Path=IsBusy}" >
<!-- Some controls here -->
</extToolkit:BusyIndicator>

private void DoSomethingInteresting() {

// Set the IsBusy property to true which fires the
// notify property changed event
IsBusy = true;

// Do something that takes a long time
Thread t = new Thread(DoLongProcess);
t.Start();
t.Join();

// We're done. Close the Windows Form
IsBusy = false;
_hostForm.Close();

}

最佳答案

在这种情况下,最好的做法是在您实际调用关闭表单之前,通知所有系统您将要关闭,这将使您有机会在最后运行任何进程。当您完成并想从另一个线程关闭表单时,您需要在 UI 线程上使用以下方法调用它:

_hostForm.BeginInvoke(new Action(() => _hostForm.Close()));

如果您可能总是从另一个线程关闭表单,那么创建一个线程安全版本的 close 方法可能会更好;即:

public class MyForm : Form
{
// ...

public void SafeClose()
{
// Make sure we're running on the UI thread
if (this.InvokeRequired)
{
BeginInvoke(new Action(SafeClose));
return;
}

// Close the form now that we're running on the UI thread
Close();
}

// ...
}

使用这种方法,您可以在运行异步操作的同时继续更新表单及其 UI,然后在完成后调用关闭和清理。

关于C# 如何从另一个线程关闭主 UI 线程上的窗口窗体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8443588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com