簡體   English   中英

如何在C#異步http庫中管理大量的委托和用戶回調

[英]How to manage large amounts of delegates and usercallbacks in C# async http library

我正在用C#編寫一個.NET庫,以便使用HTTP通過其JSON RPC接口與XBMC通信。

我編碼並發布了初步版本,但是所有步驟都是同步完成的。 然后,我出於自己的目的將庫重新編碼為異步的,因為我正在/正在為WP7構建XBMC遠程服務器

現在,我想發布新的異步庫,但是在執行此操作之前,請確保它干凈整潔。

由於異步的性質,用戶會發起一個請求,提供一個與我的委托匹配的回調方法,然后在收到響應后處理該響應。

我的問題是,在庫中我跟蹤請求的生命周期內的RequestState對象,它包含http請求/響應以及用戶回調等作為成員變量,如果僅一種類型的對象,這會很好回來了,但取決於用戶的呼叫方式,他們可能會返回歌曲列表或電影列表等。

目前,我的實現使用單個委托ResponseDataRecieved,該委托具有單個參數,這是一個簡單的對象-由於這僅由我使用,因此我知道哪些方法返回什么,以及在我處理響應時,我將對象轉換為已知的類型確實是-清單,清單等

第三方不必這樣做-委托簽名應包含正確類型的對象。 因此,對於每種可以返回給第三方的響應數據類型,我都需要一個委托-特定的問題是,如何在內部優雅地處理此問題-我是否有一堆不同的RequestState對象,每個對象都有不同的成員變量給不同的代表? 那並不“感覺”正確。 我只是不知道如何優雅而干凈地做到這一點。

如果我對您的理解正確,那么您的接口將提供多種方法,每種方法基本上都使用相同的委托,但是會獲得不同類型的參數作為輸入。 像這樣:

GetListOfSongs(..., delegate(List<Song> result) { ... });
GetListOfMovies(..., delegate(List<Movie> result) { ... });

並且您擔心委托簽名隨接口中的方法一起出現嗎?

如果是這樣,那么泛型就是您要尋找的。 實際上,如果您的委托人簽名與我的示例匹配-也就是說,接受一個輸入參數,則不返回任何值-您想要的委托人類型已經存在於BCL中。 它稱為Action<T> 您可以像上面這樣聲明方法:

GetListOfSongs(..., Action<List<Song>> callback);
GetListOfMovies(..., Action<List<Movie>> callback);

並且您仍然只有一個委托類型,即Action<T>

現在,如果您需要傳遞多個參數,那么您仍然可以解決。 存在多達16個輸入參數的Action版本(盡管它們的簽名開始顯得有些扎眼: Action<T1, T2, T3 ...> )。

如果您希望回調函數還返回將在基礎結構中某個地方使用的值,則Func<T, TResult>是您的朋友(T是輸入參數的類型,TResult是您將從其返回的值的類型代表)。

另外,我建議您不要在界面中公開List<T> 如果您真的認為所有客戶端都需要列表操作,請使用IList<T> ,但如果不需要,請考慮使用ICollection<T>甚至IEnumerable<T>

首先想到的是泛型: ResponseDataRecieved<T> ,其中T是回調中期望的類型。 但是,您可以將回調保存為捕獲的變量。 例如:

public delegate void CallBackA(int i);
public delegate void CallBackB(string s);

public class RequestHandler
{
    public void QueueRequestA(CallBackA callback)
    {
        Task.Factory.StartNew(() =>
                                  {
                                      int ret = 0;
                                      //ret = get stuff of type A from server
                                      callback(ret); //callback is captured here
                                  });
    }

    public void QueueRequestB(CallBackB callback)
    {
        Task.Factory.StartNew(() =>
                                  {
                                      string str = "";
                                      //str = get stuff of typw B from server
                                      callback(str); //callback is captured here
                                  });
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM