异步呼叫最佳实践

时间:2010-11-10 00:26:05

标签: c# winforms wcf asynchronous

我正在使用vs.NET 2010和C#windows窗体开发一个Windows应用程序。此应用程序具有用户控件,用于查询服务(在win服务上托管的WCF),并且需要在不阻止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(); })); }
    });
}

1 个答案:

答案 0 :(得分:3)

您的解决方案没有任何问题,但您可以使用BackgroundWorker更轻松地完成解决方案。

BackgroundWorker处理线程异常,在WPF窗口上调用Invoke,并帮助进行报告和取消。更多示例here

P.S。 C#的未来版本可能会使这更容易 - 请查看Async CTP