Async method in Button

I'm trying to write an app to get some json from the internet asynchronously and pull data from that json after a button press. This is the button event handler:

button.Click += delegate { Task<string> awaitOperator = KC.GetFromAPI(); json = await awaitOperator; double price = KC.DecodeJSON(json); button.Text = string.Format("ETH: {0} Bitcoin", price); };

And this is the GetFromAPI method:

public async Task<string> GetFromAPI() { using (WebResponse wr = WebRequest.Create("https://api.kraken.com/0/public/Ticker?pair=XETHXXBT").GetResponse()) { using (StreamReader sr = new StreamReader(wr.GetResponseStream())) { return sr.ReadToEnd(); } } }

I get: "The await operator can only be applied to an async method. Consider marking this method with the 'async' modifier." on "await awaitOperator;"

and: "This async method lacks 'await' operators and will run synchronously." on the GetFromAPI decleration.

What am I doing wrong?

Thanks!

Answers

  • Michael_ShapiroMichael_Shapiro USMember ✭✭✭
    edited July 2016

    In C# the async and await are used in pair: The line of code that has an await must be within the method (procedure) that is defined as async. Here is the primitive pseudo code:

    public ASYNC Task<string> MyMethod()
    {
        some code;
        some code;
    
        string s = AWAIT SomeAsyncCall();
    
        some code;
        some code;
    
        return s;
    }
    

    In your code, most likely, procedure that has the button click event and the code inside it is not marked as ASYNC. On the flip side, your GetFromAPI() method is marked as ASYNC... but there is no await operator inside this procedure.

  • MihaMarkicMihaMarkic SI ✭✭✭✭
    edited July 2016

    FTFY (mark delegate as async)

    button.Click += async delegate
                {
                    json = await  KC.GetFromAPI();
                    double price = KC.DecodeJSON(json);
                    button.Text = string.Format("ETH: {0} Bitcoin", price);
                };
    
  • MattyABMattyAB GBMember

    Ok, that's fixed the error, but it is still running the http request synchronously. I am still getting the "This async method lacks 'await' operators and will run synchronously." warning, and so it needs to run the HTTPRequest Asynchronously. How can I do this?

  • MihaMarkicMihaMarkic SI ✭✭✭✭

    Something like this should do the trick. You might dispose response as well (me lazy).

    using (HttpWebRequest wr = (HttpWebRequest)WebRequest.Create("https://api.kraken.com/0/public/Ticker?pair=XETHXXBT"))
                {
            var response = (HttpWebResponse)await wr.GetResponseAsync();
                    using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                    {
    
                        return await sr.ReadToEndAsync();
                    }
                }
    
  • MattyABMattyAB GBMember

    That looks right, but I get the error:

    'HttpWebRequest': Type used in a using must be implicitly convertible to 'System.IDisposable'

    How can I fix this?

  • MihaMarkicMihaMarkic SI ✭✭✭✭

    If it isn't disposable then don't dispose it (doesn't need to) :)

Sign In or Register to comment.