简体   繁体   English

SaveFileDialog不显示在新线程中吗?

[英]SaveFileDialog doesn't show in new thread?

I've been confused by this problem for a very long time. 很长一段时间以来,我一直对此问题感到困惑。 I start the new thread by using System.Threading, just like this: 我使用System.Threading启动新线程,如下所示:

ParameterizedThreadStart threadFileExport = FileExport;
Thread threadExport = new Thread(threadFileExport)
{
    IsBackground = true,
    Name = "threadExport",
    Priority = ThreadPriority.AboveNormal
};
threadExport.Start(_dataTable);

and

public void FileExport(object objTable)
{

     SaveFileDialog saveFileDialog = new SaveFileDialog
     {
         DefaultExt = "xlsx",
         Filter = "Excel 2007-2010|*.xlsx|" +
                  "Excel95,97,2003|*.xls|",
         FileName = "table.xlsx",
         Title = "Save as. . ."
     };
saveFileDialog.ShowDialog();
}

But the dialog won't show and it seems that the thread will abort immediately when executing "ShowDialog". 但是对话框不会显示,并且似乎在执行“ ShowDialog”时线程将立即中止。 Is this a bug or I made a mistake? 这是一个错误还是我犯了一个错误? Can a background thread shows a savefile dialog? 后台线程可以显示保存文件对话框吗?

不,必须像其他任何UI操作一样,在UI线程上显示一个对话框。

The thread you created doesn't establish a message loop, so you cannot show it. 您创建的线程不会建立消息循环,因此您无法显示它。

Better is to ask user the file path on the UI thread and then start your export thread, passing it the file name. 更好的方法是询问用户UI线程上的文件路径,然后启动导出线程,并向其传递文件名。 Still better is using a BackgroundWorker thread so that your UI remains responsive. 更好的是使用BackgroundWorker线程,以便您的UI保持响应。

Update: If you cannot use BackgroundWorker, below is the code for the alternative I described. 更新:如果您不能使用BackgroundWorker,下面是我描述的替代代码。 I assume you have a method similar to ExportDataTableToFile which you call after you get the file name. 我假设您有一个类似于ExportDataTableToFile的方法,在获取文件名后将调用该方法。

//
// Assuming your actual export method is similar to this:    
//
void ExportDataTableToFile(DataTable dataTable, string fileName) {
    // ...
}

And I assume you're on the UI thread here: 我假设您在此处使用UI线程:

//
// You can ask for the file path first;
//
SaveFileDialog saveFileDialog = new SaveFileDialog
{
     DefaultExt = "xlsx",
     Filter = "Excel 2007-2010|*.xlsx|" +
              "Excel95,97,2003|*.xls|",
     FileName = "table.xlsx",
     Title = "Save as. . ."
};
saveFileDialog.ShowDialog();


string fileName = null;
if(saveFileDialog.Result == DialogResult.OK) // "else" case should be added
    fileName = saveFileDialog;

//
// And then start the thread:
//
Thread threadExport = new Thread(() => ExportDataTableToFile(_dataTable, fileName))
{
    IsBackground = true,
    Name = "threadExport",
    Priority = ThreadPriority.AboveNormal
};
threadExport.Start();

try this 尝试这个

in your class 在你班上

private object sync_temp = new object();

and in thread method 和线程方法

string path;
SaveFileDialog save = new SaveFileDialog();
// your code to do with "save"
Action ac = () => { lock (sync_temp) { save.ShowDialog(); } };
Invoke(ac);
lock (sync_temp)
{
   path = save.FileName;
}

or mark that thread as STAThread 或将该线程标记为STAThread

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM