2014-10-06 40 views
0

第一次在這裏問一個問題,我會盡量做到儘可能具體。不能得到Task.Result返回字符串,除非我添加一個Thread.Sleep

我正在使用基於Web的Api工作,我很難得到任務以返回結果。

我有一個貿易類這樣與一個買方法和一個GetOrderNumber方法。在我的MainForm中,我使用任務來執行交易,然後檢索與該交易相關的訂單號。

NewTrade Test = new NewTrade(); 

Task<string> tmp = Task.Factory.StartNew(() => Test.Buy("JPM.NY", 100, 59.50)); 
string reqid = tmp.Result; 

Task<string> tmp2 = Task.Factory.StartNew(() => Test.GetOrderNumber(reqid)); 

Console.WriteLine(tmp2.Result); 

第一個任務返回一個REQID號碼。第二項任務使用REQID號碼並返回交易放置的實際訂單編號。

我遇到的問題是我從第一個任務獲得ReqID號碼,但是我在第二個任務中返回空白。

但是,如果我在第一個和第二個任務之間添加一個Thread.sleep(),我會得到訂單號。

我使用任務因爲最終會有數百個訂單被放置,所以每個訂單都有訂單號碼至關重要。

class NewTrade 
{ 
    public string Buy(string stkName, int stkShares, double limitPrice) 
    { 
     try 
     { 
      using (MyWebClient client = new MyWebClient()) 
      { 

       Stream data = client.OpenRead("http://localhost:8080/ExecuteOrder?symbol=" + stkName + "&limitprice=" + limitPrice + "&ordername=ARCA%20Buy%20ARCX%20Limit%20DAY&shares=" + stkShares); 
       StreamReader reader = new StreamReader(data); 
       string s = reader.ReadToEnd(); 
       s = getBetween(s, "<Content>", "</Content>"); //this is a util function to parse the result 
       // MessageBox.Show(s.ToString()); 
       data.Close(); 
       reader.Close(); 

       return s; 
      } 
     } 
     catch (WebException e) 
     { 
      Console.WriteLine(e.Message); 
      Console.WriteLine(e.StackTrace); 
      return "Nothing"; 
     } 
    } 

    public string GetOrderNumber(string id) 
    { 
     string s = ""; 

     using (MyWebClient client = new MyWebClient()) 
     { 
      try 
      { 
       WebRequest request = WebRequest.Create("http://localhost:8080/GetOrderNumber?requestid=" + id); 
       WebResponse response = request.GetResponse(); 
       var reader = new StreamReader(response.GetResponseStream()); 

       s = reader.ReadToEnd(); 
       Console.WriteLine(s); 
       return s; 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
       return ""; 
      } 
     } 
    } 
} 
+0

@Valmorgal然後[編輯你的問題](http://stackoverflow.com/posts/26226337/edit)並使其顯示。還可以使用@ not - 讓您正在與之交談的用戶發表意見。請提出您的問題的[SSCCE](http://sscce.org/),我們可以複製代碼並自行運行以查看它發生的情況是最好的(您可以在沒有WebClient調用的情況下複製問題嗎?) – 2014-10-06 23:27:10

+0

@ScottChamberlain會做。 – Valmorgal 2014-10-06 23:28:15

+0

@ScottChamberlain我一直在嘗試各種各樣的事情,因爲OrderNumber方法現在正在使用webrequest從本地Web服務器獲取響應,並且它是同一個問題。我也使用過WebClient,也是同樣的問題。 – Valmorgal 2014-10-06 23:35:45

回答

2

使用Task S能夠使應用程序更具有可擴展性要啓用線程來處理其他任務而異步任務正在進行中。也就是說,使用Task.RunTask.Factory.StartNew在後臺執行IO任務會失敗該目的。您需要通過調用您正在使用的IO構造的async API來使您的方法真正成爲async。試着改變你的代碼是這樣的:

public Task<string> MakeTradeAsync() 
{ 
    NewTrade Test = new NewTrade(); 

    string reqid = await Test.Buy("JPM.NY", 100, 59.50); 

    string orderNumber = await Test.GetOrderNumber(reqid); 

    Console.WriteLine(orderNumber); 

    return orderNumber; 
} 

這需要你做出Test.BuyTest.GetOrderNumber異步爲好。您可以通過使用async API來訪問您的服務器數據。

public async Task<string> Buy(string stkName, int stkShares, double limitPrice) 
{ 
    try 
    { 
     using (MyWebClient client = new MyWebClient()) 
     { 
      // use async API here to get the data, assuming existance of OpenReadAsync 
      Stream data = await client.OpenReadAsync("http://localhost:8080/ExecuteOrder?symbol=" + stkName + "&limitprice=" + limitPrice + "&ordername=ARCA%20Buy%20ARCX%20Limit%20DAY&shares=" + stkShares); 
      StreamReader reader = new StreamReader(data); 
      string s = reader.ReadToEnd(); 
      s = getBetween(s, "<Content>", "</Content>"); //this is a util function to parse the result 
      // MessageBox.Show(s.ToString()); 
      data.Close(); 
      reader.Close(); 

      return s; 
     } 
    } 
    catch (WebException e) 
    { 
     Console.WriteLine(e.Message); 
     Console.WriteLine(e.StackTrace); 
     return "Nothing"; 
    } 
} 

public async Task<string> GetOrderNumber(string id) 
{ 
    string s = ""; 

    using (MyWebClient client = new MyWebClient()) 
    { 
     try 
     { 
      WebRequest request = WebRequest.Create("http://localhost:8080/GetOrderNumber?requestid=" + id); 
      WebResponse response = await request.GetResponseAsync(); 
      var reader = new StreamReader(response.GetResponseStream()); 

      s = await reader.ReadToEndAsync(); 
      Console.WriteLine(s); 
      return s; 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
      return ""; 
     } 
    } 
} 
+0

我嘗試使用建議的更改,但仍遇到空白返回的問題。如果我的Thread.Sleep(50)在開始的OrderNumber方法一切正常....我不知道爲什麼... – Valmorgal 2014-10-07 01:52:05

+0

可能有一些異步操作發生在服務器上,所以做睡眠導致它及時完成下一次通話。當你調用'client.OpenRead'時,我會查看服務器端發生的情況。 – 2014-10-07 02:45:38

+0

與其他交易者交談,他們可以在交易執行後的2毫秒內從同一服務器上獲取信息。他使用python雖然... – Valmorgal 2014-10-07 02:59:15

相關問題