2010-11-16 48 views
0

我在我的智慧結束試圖解決這個問題。需要幫助訪問數據來自回調C#.NET

我有一個類中的功能,例如

public class ReceiveData 
{ 
    Dataprovider provider = new DataProvider(); 

    public void ResponseData() 
    { 
     foreach(string anItem in TheList) 
     { 
      // AllData function is declared in class DataProvider 
      string result = provider.AllData(anItem); 
     } 

     //do something 
    } 
} 

這很簡單。但是,如果AllData函數必須進行異步函數調用以獲取數據,我該怎麼辦?

含義,說

public class DataProvider 
{ 
    MyServiceClient client = new MyServiceClient(); 

    public string AllData (string myItem) 
    { 
     client.FormattedDataCompleted += new EventHandler<FormattedDataCompletedEventArgs>(client_FormattedDataCompleted); 
     client.FormattedDataAsync(myItem); 
    } 

    void client_FormattedDataCompleted(object sender, FormattedDataCompletedEventArgs e) 
    { 
     // here's where the response comes back. 
    } 

正如你所看到的,現在我不能簡單地調用ALLDATA功能,並直接找回數據。

那麼,我需要做什麼在ResponseData函數中確保我調用AllItem函數,並從回調中獲取數據。請注意,該函數中有一個循環,所以我需要通過循環發送的所有參數都會得到相應的響應。

我嘗試過的一種方法是使用AutoResetEvent類。

我將此處理程序定義爲 AutoResetEvent handle = new AutoResetHandle(false);

然後我在async調用之後立即添加handle.WaitOne()。並在回調中添加了handle.Set();

但是,應用程序卡在handle.WaitOne()。所以我不明白爲什麼會發生這種情況。

我現在有一個理論上的想法,看看我是否可以在回調中使用事件提升器,並在RecieveData類中使用eventlistener,如果這兩者溝通,我可以獲取數據。但我花了一些時間嘗試瞭解更多關於事件處理程序的知識,但還沒有掌握它。

那麼有沒有人有任何其他的方法,想法?謝謝!

+0

Sooo ...只是想了解...你想阻止請求的異步結果?你不想異步處理你的數據? – 2010-11-16 15:33:15

+0

在球部分,是 – Qgalore 2010-11-16 18:26:49

回答

0

歡迎使用異步模型。當你使用多線程時,你必須重新思考你如何調用方法。

你有一些選擇:

  • 拆分的方法,其中你讓通話成兩半;在上半部分中,調用AllData,做任何其他的事情,否則你可能沒有響應對象,然後退出當前的方法。當異步調用完成時,它會調用您的處理程序,您應該在那裏執行需要響應的原始方法中的所有操作。

  • 在異步調用完成的事件處理程序中,設置一個指示調用已完成的屬性,並將數據放在某處的某個屬性上。在啓動呼叫的功能中,在呼叫完成之前無法繼續執行的地方,請等待一段時間循環後,通過輪詢該屬性完成呼叫,並在呼叫完成後斷開,表明呼叫已完成(您的呼叫已完成)你可能需要一個Thread.Yield()以及當你還沒有得到響應時調用,以確保你不會阻止其他線程做比等待更重要的事情)

  • 將您的異步調用包裝在公開同步方法的類中。包裝類將具有與將異步調用集成到方法中相似的邏輯。它將進行調用,等待響應,並將該響應作爲普通的同步方法調用返回。

請記住,異步調用讓您的調用線程有機會在調用時執行其他工作。儘可能充分利用這一點。

0

你只需要使用委託並調用BeginInvoke。然後,您可以設置一個回調方法來捕獲委託調用的結果。

public class ReceiveData 
{ 
    private List<string> TheList = new List<string> 
    { 
     "1", "2", "3" 
    }; 

    dynamic provider = new ExpandoObject(); 

    public void ResponseData() 
    { 
     foreach (string anItem in TheList) 
     { 
      // AllData function is declared in class DataProvider 
      Func<string, string> asyncAllData = provider.AllData; 
      asyncAllData.BeginInvoke(anItem, AllDataDone, null); 
     } 
     //do something 
    } 

    private void AllDataDone(IAsyncResult iar) 
    { 
     AsyncResult ar = (AsyncResult)iar; 
     var del = (Func<string, string>)ar.AsyncDelegate; 
     // here's your result 
     string result = del.EndInvoke(iar); 
    } 
} 
+0

嗨史蒂文,謝謝你的職位。我試圖根據您提供的概念開展工作。但是,語句Func asyncAllData = provider.AllData;返回一個錯誤'System.Dynamic.ExpandoObject'不包含'AllData'的定義。「我必須做任何事情來確保在運行時拾取函數嗎? – Qgalore 2010-11-16 18:56:09