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スレッドのファイルパスをユーザーに確認してから、エクスポートスレッドを開始し、ファイル名を渡すことをお勧めします。UIの応答性を維持できるように、 BackgroundWorkerスレッドを使用することをお勧めします。

更新: 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 に答える