0

I'm having some trouble getting the data from TaskCompleteSource. I am making an Async request to the server, and it should be returning the HTML from the login page. This works synchronous, but not Asyn.

When calling client.ExecuteAsync is it waiting for the response before it tries to get the data from the TaskCompleteSource? I'm very confused about what's going on here.

public Task<bool> login()
    {
        var tcs1 = new TaskCompletionSource<CsQuery.CQ>();
        var tcs2 = new TaskCompletionSource<bool>();

        RestSharp.RestRequest request;
        CsQuery.CQ dom;

        request = new RestSharp.RestRequest("/accounts/login/", RestSharp.Method.GET);

        client.ExecuteAsync(request, (asyncResponse, handle) =>
        {
            tcs1.SetResult(asyncResponse.Content);

        });

        // Get the token needed to make the login request
        dom = tcs1.Task.ToString();

        // Other Code
James Jeffery
  • 12,093
  • 19
  • 74
  • 108

1 Answers1

0

The ExecuteAsync method returns straight away, if you want to process the response you need to set up a task continuation.

    var tcs1 = new TaskCompletionSource<CsQuery.CQ>();
    var tcs2 = new TaskCompletionSource<bool>();

    RestSharp.RestRequest request;
    CsQuery.CQ dom;

    request = new RestSharp.RestRequest("/accounts/login/", RestSharp.Method.GET);

    client.ExecuteAsync(request, (asyncResponse, handle) =>
    {
        tcs1.SetResult(asyncResponse.Content);

    });

    tcs1.Task.ContinueWith( () =>
    {   
        // Get the token needed to make the login request
        dom = tcs1.Task.ToString();

        // Other Code
    });

If you are using .NET 4.5 you can also use the new async/await syntax. I've modified the type of the TaskCompletionSource to be a string as I don't have access to the CsQuery.CQ type.

public async Task<bool> login()
{
    var tcs1 = new TaskCompletionSource<string>();

    RestSharp.RestRequest request;

    request = new RestSharp.RestRequest("/accounts/login/", RestSharp.Method.GET);

    client.ExecuteAsync(request, (asyncResponse, handle) =>
    {
        tcs1.SetResult(asyncResponse.Content);

    });

    await tcs1.Task;

    // Other Code ...

    return true;
} 
NeddySpaghetti
  • 13,187
  • 5
  • 32
  • 61
  • How can the ExecuteAsync be used with await to ensure it waits? I've tried to use await but don't seem to work. – James Jeffery Aug 11 '13 at 11:44
  • you can do `tcs1.Task.Wait()` but that would essentially make it synchronous and would defeat the purpose of calling it asynchronously. If there is an overload of `ExecuteAsync` that returns a `Task` and you are using .net 4.5 you can do `await ExecuteAsync`. I'll amend my answer to show you the await version. – NeddySpaghetti Aug 11 '13 at 23:39
  • Have a look at this article, it explains some of the pitfalls of asynchronous programming http://msdn.microsoft.com/en-us/magazine/jj991977.aspx – NeddySpaghetti Aug 11 '13 at 23:49