Запуск метода в отдельном потоке и ошибка с диалогом сохранения файла - PullRequest
0 голосов
/ 06 апреля 2011
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 Ответ

1 голос
/ 06 апреля 2011

Помните, что все объекты 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);
    }
}
...