C# 在单独的线程中运行方法,并在“保存文件”对话框中出错
单击按钮1时,导出方法将在单独的线程中调用,不会引发错误,但保存文件对话框不会出现错误。所以请告诉我代码中的错误是什么。我的方法在单独的线程中调用方法是错误的。另请说明plzz保存文件对话框未打开。我需要纠正哪些方面。请解释一下。谢谢。请记住,所有Winforms对象都应该从主UI线程使用。因此,在单独的线程中,必须使用Invoke/BeginInvoke。如果可以的话,在UI线程中执行所有“Winforms”操作,然后使用所需的所有数据/信息运行单独的线程 我认为,更好的方法是:C# 在单独的线程中运行方法,并在“保存文件”对话框中出错,c#,.net,winforms,multithreading,savefiledialog,C#,.net,Winforms,Multithreading,Savefiledialog,单击按钮1时,导出方法将在单独的线程中调用,不会引发错误,但保存文件对话框不会出现错误。所以请告诉我代码中的错误是什么。我的方法在单独的线程中调用方法是错误的。另请说明plzz保存文件对话框未打开。我需要纠正哪些方面。请解释一下。谢谢。请记住,所有Winforms对象都应该从主UI线程使用。因此,在单独的线程中,必须使用Invoke/BeginInvoke。如果可以的话,在UI线程中执行所有“Winforms”操作,然后使用所需的所有数据/信息运行单独的线程 我认为,更好的方法是: privat
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");
}
}
private void按钮1\u单击(对象发送者,事件参数e){
这个是Export();
}
私有void导出(){
System.Data.DataTable dt=(System.Data.DataTable)this.dgResult.DataSource;
如果(dt.Rows.Count>0){
//初始化保存文件对话框
DialogResult rslt=this.svDialog.ShowDialog(this);
如果(rslt==DialogResult.OK){
string filePath=this.svDialog.FileName;
//QueueUserWorkItem在单独的线程中运行目标委托
ThreadPool.QueueUserWorkItem((_state)=>this.Export(dt,filePath));
}
}
否则{
//…其他一些代码。。。。
}
}
私有void导出(数据表数据、字符串文件路径){
Exception thrownException=null;
请尝试{Business.ExportToExcel.ExcelFromDataTable(dt,filePath);}
catch(异常exc){thrownException=exc;}
if(null==thrownException){MsgBox(“导出完成”);}
else{MsgBox(“错误:+thrownException.Message”);}
}
专用void MsgBox(字符串文本){
if(this.invokererequired){
Action dlg=this.MsgBox;
调用(dlg,text);
}
否则{
MessageBox.Show(这个,文本);
}
}
谢谢您的代码,但我不明白您给出的2行代码。Action dlg=this.MsgBox;调用(dlg,text);在这里,您使用来自同一函数的action delegate指定一个函数名。为什么plzz解释“Action dlg=this.MsgBox”。创建没有返回值(void)和一个字符串参数的委托。该委托指向方法“MsgBox”。它与“Action dlg=newaction(this.MsgBox);”相同。“this.Invoke(dlg,text)”将在UI线程中调用传递的委托(本例中为this.MsgBox),并将“text”作为第一个参数传递。我最喜欢的关于Winforms的Invoke/BeginInvoke的文章是关于CodeProject的:MsgBox中的整个构造具有非常重要的行为。如果您将从UI线程以外的其他线程调用MsgBox,“this.InvokeRequired”将为true,并且需要Invoke/BeginInvoke。因此,“MsgBox”方法将在UI线程中调用self。它在您希望从UI和并行线程使用相同方法的场景中非常有用。
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);
}
}