Запуск метода в отдельном потоке и ошибка с диалогом сохранения файла
private void button1_Click(object sender, EventArgs e)
{
new System.Threading.Thread(delegate()
{
Export();
}).Start();
}
private void Export()
{
int rowcount = ((System.Data.DataTable)this.dgResult.DataSource).Rows.Count;
System.Data.DataTable dt = (System.Data.DataTable)this.dgResult.DataSource;
if (rowcount > 0)
{
if (InvokeRequired)
{
BeginInvoke(new MethodInvoker(delegate()
{
svDialog.Filter = "Excel|*.xls";
svDialog.Title = "Save an Excel File";
svDialog.ShowDialog();
if (svDialog.FileName != "")
{
Business.ExportToExcel.ExcelFromDataTable(dt, svDialog.FileName);
MessageBox.Show("Export completed");
}
}));
}
else
{
svDialog.Filter = "Excel|*.xls";
svDialog.Title = "Save an Excel File";
svDialog.ShowDialog();
if (svDialog.FileName != "")
{
Business.ExportToExcel.ExcelFromDataTable(dt, svDialog.FileName);
MessageBox.Show("Export completed");
}
}
}
else
{
MessageBox.Show("No data found");
}
}
при нажатии кнопки 1 метод экспорта вызывается в отдельном потоке, и ошибка не возникает, но диалог сохранения файла не вызывает ошибку. поэтому, пожалуйста, скажите мне, в чем моя ошибка в коде. Мой подход неверно вызывать метод в отдельном потоке. Также объясните, плз сохранить файл диалоговое окно не открывается. какую область мне нужно исправить. пожалуйста объясните. Благодарю.
1 ответ
Помните, что все объекты Winforms должны использоваться из основного потока пользовательского интерфейса. Так что в отдельном потоке вы ДОЛЖНЫ использовать Invoke/BeginInvoke. Если вы можете, сделайте все "Winforms вещи" в потоке пользовательского интерфейса и после этого запустите отдельный поток со всеми необходимыми данными / информацией.
Я думаю, что лучший способ это:
private void button1_Click(object sender, EventArgs e) {
this.Export();
}
private void Export() {
System.Data.DataTable dt = (System.Data.DataTable)this.dgResult.DataSource;
if ( dt.Rows.Count > 0 ) {
// initialize save file dialog
DialogResult rslt = this.svDialog.ShowDialog(this);
if ( rslt == DialogResult.OK ) {
string filePath = this.svDialog.FileName;
// QueueUserWorkItem runs target delegate in separate thread
ThreadPool.QueueUserWorkItem( (_state)=> this.Export(dt, filePath) );
}
}
else {
// ... some other code ....
}
}
private void Export(DataTable data, string filePath) {
Exception thrownException = null;
try { Business.ExportToExcel.ExcelFromDataTable(dt, filePath); }
catch( Exception exc ) { thrownException = exc; }
if ( null == thrownException ) { MsgBox("Export completed."); }
else { MsgBox("Error: " + thrownException.Message); }
}
private void MsgBox(string text) {
if (this.InvokeRequired) {
Action<string> dlg = this.MsgBox;
this.Invoke( dlg, text );
}
else {
MessageBox.Show(this, text);
}
}