很长一段时间以来,我一直对这个问题感到困惑。我使用System.Threading启动新线程,就像这样:
ParameterizedThreadStart threadFileExport = FileExport;
Thread threadExport = new Thread(threadFileExport)
{
IsBackground = true,
Name = "threadExport",
Priority = ThreadPriority.AboveNormal
};
threadExport.Start(_dataTable);
和
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();
}
但是对话框不会显示,似乎线程在执行“ShowDialog”时会立即中止。这是一个错误还是我弄错了?后台线程可以显示保存文件对话框吗?
答案 0 :(得分:5)
不,必须在UI线程上显示对话框,就像任何其他UI操作一样。
答案 1 :(得分:2)
您创建的主题没有建立消息循环,因此您无法显示它。
最好是询问用户UI线程上的文件路径,然后启动导出线程,并传递文件名。更好的是使用BackgroundWorker线程,以便您的UI保持响应。
<强>更新强>
如果您不能使用BackgroundWorker,下面是我所描述的替代方案的代码。
我假设您有一个类似于ExportDataTableToFile
的方法,您在获得文件名后调用它。
//
// Assuming your actual export method is similar to this:
//
void ExportDataTableToFile(DataTable dataTable, string fileName) {
// ...
}
我假设你在这里的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();
答案 2 :(得分:1)
试试这个
你班上的
private object sync_temp = new object();
和线程方法
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;
}
或将该线程标记为STAThread