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