Лучшие практики асинхронного вызова - PullRequest
0 голосов
/ 10 ноября 2010

Я занимаюсь разработкой приложения для Windows с Windows 2010 и C # формами.Это приложение имеет пользовательский элемент управления, который запрашивает службу (WCF, размещенную на win-сервисе) и должен делать это без блокировки пользовательского интерфейса.Пользовательский элемент управления содержит сетку, которая покажет эти результаты.Я думаю, что моя ситуация наиболее распространена.Мой вопрос к вам, что можно сделать с 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 Ответ

3 голосов
/ 10 ноября 2010

В вашем решении нет ничего плохого, хотя вы можете сделать это проще с BackgroundWorker .

BackgroundWorker обрабатывает исключения потоков, вызывает Invoke в окне WPF и помогает с отчетами о прогрессе и отменой. Больше примеров здесь .

P.S. Будущие версии C # могут сделать это еще проще - посмотрите Async CTP .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...