0
我正在开发与vsNET 2010和C#窗体窗体的Windows应用程序。这个应用程序有一个查询服务的用户控件(WCF托管在win服务上),并且需要在不阻止UI的情况下执行此操作。用户控件包含一个将显示结果的网格。我认为我的情况最为常见。我对你的问题是用C#可以做些什么,以使下面的代码运行更平滑,并具有更好的错误处理。我正在使用MehtodInvoker,因此我可以避免为此调用写入两个分离方法 - 等待 - 填充方案。异步调用最佳实践
public void LoadData()
{
StartWaitProgress(0);
ThreadPool.QueueUserWorkItem(x =>
{
try
{
MyDocMail[] mails;
var history = Program.NoxProxy.GetDocumentHistory(out mails, Program.MySessionId, docId);
this.Invoke(new MethodInvoker(delegate()
{
this.SuspendLayout();
gridVersions.Rows.Clear();
foreach (var item in history)
{
gridVersions.Rows.Add();
int RowIndex = gridVersions.RowCount - 1;
DataGridViewRow demoRow = gridVersions.Rows[RowIndex];
demoRow.Tag = item.Id;
if (gridVersions.RowCount == 1)
{
demoRow.Cells[0].Value = Properties.Resources.Document_16;
}
demoRow.Cells[1].Value = item.Title;
demoRow.Cells[2].Value = item.Size.GetFileSize();
demoRow.Cells[3].Value = item.LastModified;
demoRow.Cells[4].Value = item.CheckoutBy;
demoRow.Cells[5].Value = item.Cotegory;
}
gridEmails.Rows.Clear();
foreach (var item in mails)
{
gridEmails.Rows.Add();
int RowIndex = gridEmails.RowCount - 1;
DataGridViewRow demoRow = gridEmails.Rows[RowIndex];
demoRow.Tag = item.Id;
demoRow.Cells[1].Value = item.From;
demoRow.Cells[2].Value = item.To;
demoRow.Cells[3].Value = item.Date;
}
this.ResumeLayout();
}));
}
catch (Exception ex)
{
Program.PopError(ex);
this.Invoke(new MethodInvoker(delegate() { this.Close(); }));
}
finally { this.Invoke(new MethodInvoker(delegate() { StopWaitProgress(); })); }
});
}
你也可以使用.NET 4框架中的任务来清理它。 – 2010-11-10 04:37:35
我已经在C#2.0中尝试过BackgroundWorker解决方案,但我没有看到任何优势,我使用BackgroundWorker将代码分离到多个方法/事件中。在我的应用程序中,有些情况下,我可以在10次调用wcf服务的同一窗体中进行操作。为了加速这个调用,我必须让它们在同一时间(在ThreadPool上并行运行),以便产生BackgroundWorker的10个实例...上面的代码更加紧凑,因为我可以为每个异步调用。 – 2010-11-10 09:12:55
请记住,您可以以编程方式实例化BackgroundWorker,并使用匿名方法或lambda表达式来处理事件(这通常是我所做的)。最好的解决方案取决于你的最终目标。你能详细说明你的意思是“更平滑,更好的错误处理”吗? – 2010-11-10 10:53:07