【问题标题】:Closing a WPF within Thread - C#在线程中关闭 WPF - C#
【发布时间】:2014-11-23 21:27:01
【问题描述】:

我有一个显示对话框的线程。我为此使用线程的原因是因为我希望对话框立即显示(所以我使用ShowDialog()))而主线程继续做一些繁重的工作。当主线程完成“重”功能时,我希望对话框停止显示。

这是我正在使用的代码:

Thread searchingAlertThread = (new Thread(() =>
{
    SearchingAlert searchingAlert = new SearchingAlert();
    try {
        searchingAlert.ShowDialog();
    } catch (ThreadAbortException) { // Thrown when the thread is aborted
        searchingAlert.Close();
    }                        
}));
searchingAlertThread.SetApartmentState(ApartmentState.STA);

searchingAlertThread.Start(); // Starts the thread
BluetoothDeviceInfo[] devices = client.DiscoverDevices(); // Takes 15 seconds
searchingAlertThread.Abort(); // Stops the thread

searchingAlertWPF 窗口 对话框,显示 TextViewImageView 以及动画 gif。

问题是,有时当这个调用被多次调用时(以防它没有找到任何设备),ImageView 不会显示,更重要的是,ThreadAbortException 不会被抛出。 这是用对话框关闭线程的正确方法吗?

【问题讨论】:

  • 使用Invoke()Close() 对话框。
  • @SLaks 很抱歉造成误解,但它是 WPF ......我已经编辑了问题
  • 不要使用 ShowDialog。如果您需要打开一个线程只是为了在另一个窗口上创建一个窗口,这意味着有问题......为什么不打开一个窗口或创建一个显示进度的用户控件呢?

标签: c# wpf multithreading dialog


【解决方案1】:

原始示例至少存在两个主要问题:运行新的 UI 线程和中止线程。试试这个:

SearchingAlert searchingAlert = new SearchingAlert();
BluetoothDeviceInfo[] devices = null;

searchingAlert.Loaded += async (sender, e) =>
{
    devices = await Task.Run(() => client.DiscoverDevices());
    searchingAlert.Close();
};

searchingAlert.ShowDialog();

// Use the devices array here

不清楚client 是什么,但当然,如果它提供了DiscoverDevices() 方法的异步版本,你应该只等待它而不是使用Task.Run()

【讨论】:

  • 感谢 SharonKo 尝试修复我的答案中的代码。我很惊讶您的编辑被其他 SO 审阅者拒绝。这是一个很好的编辑,我已经继续并实施了您提出的更改。
猜你喜欢
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
相关资源
最近更新 更多