第一次在这里问一个问题,我会尝试尽可能具体。
我正在使用WebBased Api工作,我很难让Task返回结果。
我有一个交易类,有一个Buy方法和一个GetOrderNumber方法。在我的MainForm上,我使用Task执行交易,然后检索与该交易相关的订单号。
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编号并返回交易交易的实际ORDER NUMBER。
我遇到的问题是我从第一个任务中获取了ReqID号,但是我在第二个任务上返回空白。
如果我在第一个和第二个任务之间添加一个Thread.sleep(),我会得到ordernumbers。
我正在使用任务,因为最终会有数百个订单被放置,这对于每个订单都有订单号。
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 :(得分:2)
使用Task
可以使您的应用程序更具可伸缩性,因为您可以在异步任务正在进行时启用线程来处理其他任务。话虽这么说,使用Task.Run
或Task.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.Buy
和Test.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 "";
}
}
}