如果从非ui线程调用ShowDialog()会发生什么?

本文关键字:什么 ShowDialog ui 线程 调用 如果 | 更新日期: 2023-09-27 17:49:30

所以我现在有下面这个代码,它有一个后台工作调用showdialog()。然而,我认为UI不能在后台线程上更新,那么对话框如何显示?对话框实际上在UI线程上打开吗?会发生什么呢?

 public partial class ProgressDialog : Window
 { 
    BackgroundWorker _worker;
    public BackgroundWorker Worker
    {
      get { return _worker; }
    }
    public void RunWorkerThread(object argument, Func<object> workHandler)
    {
      //store reference to callback handler and launch worker thread
      workerCallback = workHandler;
      _worker.RunWorkerAsync(argument);
      //display modal dialog (blocks caller)
      //never returns null, but is a nullable boolean to match the dialogresult property
      ShowDialog();
    }

我得到的建议,我只是运行代码和检查,但我如何检查是否显示对话框窗口是在一个新的线程或在后台线程本身打开?我不知道该怎么确认。

无论如何,这只是一个帖子,试图帮助我理解什么是实际发生在我的代码。

不管怎样,我终于理解了更多的评论,所以我想我明白了正在发生的一切。我的大多数实际问题都不是由这个对话框引起的,它们是由从一个非ui线程更新可观察集合而控件绑定到它们引起的。

如果从非ui线程调用ShowDialog()会发生什么?

从技术上讲,你不是在主线程上改变属性,只是创建另一个对象的实例。

但是如果你对你的ShowDialog()方法进行更详细的说明,它可能会有所帮助。

我还遇到了从非ui线程调用ShowDialog()的问题。我的答案是它取决于调用ShowDialog()的线程。如果你在这个线程开始之前设置了ApartamentState属性,那么一切都会像UI线程调用的那样工作。我最终得到了这样的代码:

private async void button1_Click(object sender, EventArgs e)
{
    var foo = new Foo();
    // MessageBox.Show(foo.DirPath) - this works as a charm but 
    // if, it is called from non UI thread needs special handling as below.
    await Task.Run(() => MessageBox.Show(foo.DirPath));
}
public class Foo
{
    private string dirPath;
    public string DirPath
    {
        get
        {
            if (dirPath == null)
            {
                var t = new Thread(() =>
                {
                    using (var dirDialog = new FolderBrowserDialog())
                    {
                        if (dirDialog.ShowDialog() == DialogResult.OK)
                            dirPath = dirDialog.SelectedPath;
                    }
                }
                );
                t.IsBackground = true;
                t.SetApartmentState(ApartmentState.STA);
                t.Start();
                t.Join();
            }
            return dirPath;
        }
        set
        {
            dirPath = value;
        }
    }
}

我不知道,但我认为showDialog不创建对象只显示它。所以当你说ShowDialog时,它只告诉你要显示。所以它会在UI线程上运行,而不是在后台工作线程上(不确定)