简体   繁体   中英

Can't get Task.Result to return string unless I add a Thread.Sleep

First time asking a question here I'll try to be as specific as possible.

I am working with a WebBased Api at work and I am having a difficult time getting the Task to return a result.

I have a trade class as such with a Buy method and a GetOrderNumber method. On my MainForm I am using a Task to execute the Trade and then retrieve the ordernumber associated with that trade.

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);

The First Task returns a REQID number. The second Task uses the REQID number and returns the actual ORDER NUMBER for the Trade Placed.

The problem I'm running into is I get the ReqID number from the first task but I return blank on the second task.

IF HOWEVER I add a Thread.sleep() between the first and second task I get the ordernumbers.

I'm using Tasks becasue eventually there will be hundreds of orders being placed it's critical to have the ordernumber for every order.

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 "";
            }
        }
    }
}

Using Task s can make your application more scalable as you are enabling threads to handle other tasks while the asynchronous task is in progress. That being said, using Task.Run or Task.Factory.StartNew to do IO tasks in the background defeats that purpose. You need to make your methods truly async by calling the async API of the IO constructs you are using. Try changing your code to something like this:

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;
}

That will require you to make Test.Buy and Test.GetOrderNumber async as well. Which you can do by using async APIs to access your server data.

 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 "";
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM