2011-11-07 53 views
4

我有自定義控件,我有界面這個控件暴露給它的用戶。需要圍繞我的頭異步操作

public interface ILookupDataProvider 
{ 
    string IdColumnName { get; } 

    IEnumerable<IDataColumn> Metadata { get; set; } 

    void GetDataAsync(string parameters, 
     Action<IEnumerable<object>> onSuccess, Action<Exception> onError); 
} 

所以,這是我試圖在GetDataAsync

暴露異步操作,但我不知道如何實現我的課該方法實現了接口。我瞭解這部分,因爲我有方法將執行,然後onCompletion,onSucessonError委託將被調用。

有人可以幫助語法如何寫這些?

編輯:

它是4.0,我不能用await命令

編輯2:

我使用DevForce框架加載數據,但該樣品的緣故 - 讓我們做WCF例如服務。我如何將WCF服務調用包裝在我的界面實現中?

另外,你認爲可以像這樣創建接口來呈現異步操作嗎?例如,你會以不同的方式做事嗎?

+0

您是在使用async/await之後還是您想知道什麼? – flq

+0

你是針對.NET 3.5還是.NET 4 –

+0

我不能使用異步等待,因爲我們正在使用VS2010進行生產我想爲此接口編寫實現,並且無法弄清楚語法。即使簡單的非異步實現它應該可以幫助我理解如何針對動作編碼 – katit

回答

6

這裏的基本思想是查詢將發生後臺線程。一旦您的操作完成,您將使用onSuccessonError回調來報告新值。例如

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); 
} 
+1

不知道爲什麼'Task'或'Task '沒有被使用,這些類的全部意義在於推動異步操作完成的通知控制在該方法的邏輯之外。 – casperOne

3

你真的不想使用此模式:

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 property得到結果(這將阻止如果任務沒有完成),或當異步操作完成時,您可以再次使用ContinueWith方法來處理數據。

此外,你可以採取一個參數的CancellationToken structure實例以確定是否應取消操作:

Task<MyData> GetDataAsync(string parameters, 
    CancellationToken cancellationToken); 

同樣,ContinueWith將允許您指示要採取的行動進行取消。

請注意,這是如何在Async CTP中使用awaitasync目前正在建模的方法;他們正在返回TaskTask<T>;在代碼中執行相同的操作可以使您在準備好這些語言功能時準備好。

+0

我覺得你是正確的,但是你的例子更加複雜,讓我的頭腦:)我知道我必須但仍然。我不認爲我可以使用它,除非你向我展示如何在實現接口的類中實現它,並且例如將WCF調用包裝到此中。我不在乎取消並繼續運營。我只需要知道它什麼時候結束,例外情況或數據結果 – katit

+0

@katit,請參閱http://msdn.microsoft.com/en-us/library/dd537610%28v=VS.100%29.aspx – ebb

+0

好的,是這在Silverlight中可用?我認爲任務不可用 – katit

1

要使用任務,您可以像這樣使用它。唯一需要記住的棘手問題是在你的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" }; 
    }); 
} 
+0

不幸的是,我不能在Silverlight 4中使用任務 – katit