GetAwaiter() Method

8.9k Views Asked by At

I have a top level function like this

          var results = await client
                .For(x.Offices)
                .Select(x.NumberOfFlores, x.Hight)
                .QueryAsync();

client is my own function that does a bunch of stuff. (Not the same as ODataClient Client class)

The result of QueryAsync() returns a custom class. This class has several parameters, one of which is queryResults. This class has a GetAwaiter() function, which never works properly.

public async Task GetAwaiter()
{
        await queryResults;
}

queryResults is an object of type Task<IEnumerable<ODataEntry>>

What i want it to do is wait for the queryResults to execute, so than i can use it in the form results.QueryResults

However, i get this error after the "await queryResults"

Unable to cast object of type 'System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult]' to type 'System.Runtime.CompilerServices.INotifyCompletion'.

The getAwaiter function does execute, but i get an error as soon as i return from it.

I have tried a bunch of different things, but nothing works. What am i doing wrong?

1

There are 1 best solutions below

2
On

Task is not an awaiter, it's an awaitable. That means that you can't return it from your GetAwaiter method - it doesn't fit the contract.

If you really want to go this road (and I really don't see the point), make sure your GetAwaiter actually returns an awaiter:

public TaskAwaiter<IEnumerable<ODataEntry>> GetAwaiter()
{
  return queryResults.GetAwaiter();
}

EDIT:

If you want to return a task of a different type, you need to return a task of a different type - there's no way around it. This reeks of bad design, but you can do something like this:

public TaskAwaiter<Tuple<YourObject, IEnumerable<ODataEntry>>> GetAwaiter()
{
  return 
    queryResults
    .ContinueWith(t => Tuple.Create(this, t.Result))
    .GetAwaiter();
}

This will return both your query object and the results as two separate properties of the tuple - of course, you can use whatever other type you'd like. However, I'd still strongly suggest rethinking your current design - it looks exactly like the kind that's going to give you headaches in a year or two.