C# 无法从非UI线程显示FolderBrowser对话框吗?

C# 无法从非UI线程显示FolderBrowser对话框吗?,c#,multithreading,worker-thread,C#,Multithreading,Worker Thread,我在显示从非UI线程创建和调用的FolderBrowserDialog实例时遇到了问题。它没有得到正确的渲染 更具体地说,它不显示文件夹树,只显示“使新文件夹确定”和“取消” 我不知道您为什么要这样做。在工作线程上,计算所需的所有值都应可用。用户无需通过交互获得更多输入。 也许重新设计对你更有帮助。在启动工作线程之前,请考虑将所选文件夹提供给它 编辑(回复评论): 如果你想做一些记录,我的答案仍然适用。您的工作线程应该知道在哪里记录异常,而不是开始询问用户。 您是否使用日志框架?如果没有,请看

我在显示从非UI线程创建和调用的
FolderBrowserDialog
实例时遇到了问题。它没有得到正确的渲染

更具体地说,它不显示文件夹树,只显示“使新文件夹确定”和“取消”


我不知道您为什么要这样做。在工作线程上,计算所需的所有值都应可用。用户无需通过交互获得更多输入。
也许重新设计对你更有帮助。在启动工作线程之前,请考虑将所选文件夹提供给它

编辑(回复评论):
如果你想做一些记录,我的答案仍然适用。您的工作线程应该知道在哪里记录异常,而不是开始询问用户。

您是否使用日志框架?如果没有,请看一看,例如。在这里,您通常在xml文件中预先配置日志记录(日志级别、路径、格式等)。不需要用户交互。尽管用户可以更改日志路径(在xml文件中)。

我不确定您为什么要这样做。在工作线程上,计算所需的所有值都应可用。用户无需通过交互获得更多输入。
也许重新设计对你更有帮助。在启动工作线程之前,请考虑将所选文件夹提供给它

编辑(回复评论):
如果你想做一些记录,我的答案仍然适用。您的工作线程应该知道在哪里记录异常,而不是开始询问用户。

您是否使用日志框架?如果没有,请看一看,例如。在这里,您通常在xml文件中预先配置日志记录(日志级别、路径、格式等)。不需要用户交互。尽管用户可以更改日志路径(在xml文件中)。

所有shell对话框,包括FolderBrowserDialog,都要求将线程的COM单元设置为STA。您可能缺少Thread.SetApartmentState()调用:


请注意,您不能设置对话框的所有者,它很容易在另一个应用程序的窗口后面丢失。这使得在工作线程上显示窗体或对话框不是一个好主意。

所有shell对话框,包括FolderBrowserDialog,都要求将线程的COM单元设置为STA。您可能缺少Thread.SetApartmentState()调用:


请注意,您不能设置对话框的所有者,它很容易在另一个应用程序的窗口后面丢失。这使得在工作线程上显示表单或对话框不是一个好主意。

我想在工作线程过程中记录异常,为此我需要从用户处获取文件夹路径。这是我不想做的:硬编码!我想授予用户指定文件夹并将异常记录在文本文件中的权限。是的,我确实使用日志框架。@Manish:但将其写入xml文件并不是硬编码。。。它很容易改变。您甚至可以在程序的选项中提供路径……好吧,我编写这个程序时假设用户不是技术人员,这就是为什么我希望他选择一个文件夹来保存日志文件。@Manish:所以请使用“用户选项”对话框,用户可以在其中更改路径。但是-在工作线程操作期间要求用户提供日志文件夹不是一个好主意。我想在工作线程过程中记录异常,为此我需要从用户处获取文件夹路径。这是我不想做的:硬编码!我想授予用户指定文件夹并将异常记录在文本文件中的权限。是的,我确实使用日志框架。@Manish:但将其写入xml文件并不是硬编码。。。它很容易改变。您甚至可以在程序的选项中提供路径……好吧,我编写这个程序时假设用户不是技术人员,这就是为什么我希望他选择一个文件夹来保存日志文件。@Manish:所以请使用“用户选项”对话框,用户可以在其中更改路径。但是-在工作线程操作期间要求用户提供日志文件夹不是一个好主意。太好了。我可以这样做:如果工作线程中发生异常,那么1。停止进一步的进程,即线程2。以某种方式通知主线程,在使该异常对象对主线程3可用时发生了异常。然后从主线程调用FolderBrowser对话框??如果是,请给我一些提示如何做到这一点。你想在异常发生时显示一个输入对话框吗?那是非常不明智的。当用户理解了这个对话框的含义时,她将完全忘记她所做的导致异常的事情。使用AppData文件夹来存储日志文件。太好了。我可以这样做:如果工作线程中发生异常,那么1。停止进一步的进程,即线程2。以某种方式通知主线程,在使该异常对象对主线程3可用时发生了异常。然后从主线程调用FolderBrowser对话框??如果是,请给我一些提示如何做到这一点。你想在异常发生时显示一个输入对话框吗?那是非常不明智的。当用户理解了这个对话框的含义时,她将完全忘记她所做的导致异常的事情。使用AppData文件夹存储日志文件。
    private void button1_Click(object sender, EventArgs e) {
        var t = new Thread(() => new FolderBrowserDialog().ShowDialog());
        t.IsBackground = true;
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }