1

我被这个问题困惑了很长时间。我使用 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”时线程似乎会立即中止。这是一个错误还是我犯了一个错误?后台线程可以显示保存文件对话框吗?

4

3 回答 3

5

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

于 2012-06-28T08:03:05.837 回答
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();
于 2012-06-28T08:07:44.883 回答
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

于 2016-03-26T18:52:32.397 回答