[英]Need to wrap my head around Async operations
我有自定義控件,我有接口這個控件暴露給它的用戶。
public interface ILookupDataProvider
{
string IdColumnName { get; }
IEnumerable<IDataColumn> Metadata { get; set; }
void GetDataAsync(string parameters,
Action<IEnumerable<object>> onSuccess, Action<Exception> onError);
}
所以,我嘗試在GetDataAsync
公開異步操作
但我不知道如何在我的實現接口的類中實現此方法。 我理解這部分,因為我有方法將執行然后onCompletion
, onSucess
或onError
委托將被調用。
有人可以幫助解決如何編寫這些問題的語法嗎?
編輯:
它是4.0,我不能使用await
命令
編輯2:
我使用DevForce框架來加載數據,但是為了這個示例 - 讓我們做WCF服務。 如何在我的接口實現中包裝WCF服務調用?
另外,你認為創建這樣的接口以呈現異步操作是否可以? 例如,你會以不同的方式做事嗎?
這里的基本思想是查詢將發生在后台線程中。 操作完成后,您將使用onSuccess
和onError
回調來報告新值。 例如
void GetDataAsync(
string parameters,
Action<IEnumerable<object>> onSuccess,
Action<Exception> onError) {
WaitCallback doWork = delegate {
try {
IEnumerable<object> enumerable = GetTheData(parameters);
onSuccess(enumerable);
} catch (Exception ex) {
onError(ex);
}
};
ThreadPool.QueueUserWorkItem(doWork, null);
}
你真的不想使用這種模式:
void GetDataAsync(string parameters,
Action<IEnumerable<object>> onSuccess, Action<Exception> onError);
相反,你想使用這個:
Task GetDataAsync(string parameters);
在返回Task
,您將返回一個表示異步工作單元的實例。 從那里,API的消費者可以選擇調用ContinueWith
並決定在成功時做什么,或者是否有錯誤。
但是,您的示例中存在設計缺陷。 在一個名為GetDataAsync
的方法中,我希望返回數據。 這不是問題,您只需將簽名更改為:
Task<MyData> GetDataAsync(string parameters);
現在返回一個Task<T>
,你可以使用Result
屬性獲取結果(如果沒有完成任務,它將阻塞),或者你可以再次使用ContinueWith
方法處理異步操作時的數據完成。
此外,您可以使用參數的CancellationToken
結構實例來確定是否應取消操作:
Task<MyData> GetDataAsync(string parameters,
CancellationToken cancellationToken);
再次, ContinueWith
將允許您指示要取消的操作。
請注意,這是當前正在建模在Async CTP中使用await
和async
方法的方式; 他們正在返回Task
或Task<T>
; 在您的代碼中執行相同操作將允許您在烘焙這些語言功能時做好准備。
要使用任務,您可以像這樣使用它。 要記住的唯一棘手的事情是在UI線程中執行回調,這是通過TaskScheduler.FromCurrentSynchronizationContext()實現的,這樣您就可以更新UI或在出現問題時顯示消息框。
由於這種東西的事件驅動性質,如果你敲擊確實啟動WCF調用的按鈕,你得到的結果不會按照你發送請求的順序返回。 如果要啟動新操作,可以通過存儲已啟動的任務來取消此操作並取消上次啟動的任務,或者可以在任務運行時忽略后續請求。
private void button1_Click(object sender, EventArgs e)
{
GetDataAsync("www.data.com").ContinueWith(result =>
{
if (result.Exception != null)
{
MessageBox.Show(this, "Error: {0}" + result.Exception, "Error");
}
else
{
foreach (var obj in result.Result)
{
textBox1.Text += obj.ToString();
}
}
},
TaskScheduler.FromCurrentSynchronizationContext()
);
}
Task<IEnumerable<object>> GetDataAsync(string parameters)
{
return Task<IEnumerable<object>>.Factory.StartNew(() =>
{
Thread.Sleep(500);
// throw new ArgumentException("uups");
// make wcf call here
return new object[] { "First", "second" };
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.