komodosp
komodosp

Reputation: 3658

Task.WhenAny() (with Task.Delay()) not "timing out"

I'm finding an AsyncOperation seems to hang (I've asked about the specific hanging in another question) so I wanted to add a 'timeout', so I've implemented what I think is a fairly standard WhenAny() pattern (see below).

However, I find that on some computers(!), the task hangs, but 20 seconds later, the Task.Delay() doesn't complete (by which I mean it doesn't proceed into the else section, it just hangs forver.

On my development PC it works fine, but on a tablet with Windows 10 22H2 it doesn't!

GattDeviceServicesResult services = null;
var task = bleDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached).AsTask();

if (await Task.WhenAny(task, Task.Delay(20000)) == task)
{

    Console.WriteLine($"Found Services for device:")    

    services = task.Result;
    if (services.Services != null)
    {
        foreach (var service in services.Services)
        {
            Console.WriteLine($"Service: {service.Uuid}");
        }
    }

}
else
{
    Console.WriteLine("Timed Out while while getting service list.");
}

AsTask() is defined as follows:

public static Task<TResult> AsTask<TResult>(this IAsyncOperation<TResult> operation)
{
    // Create task completion result.
    var tcs = new TaskCompletionSource<TResult>();

    // When the operation is completed...
    operation.Completed += delegate
    {
        switch(operation.Status)
        {
            case AsyncStatus.Completed:
                tcs.TrySetResult(operation.GetResults());
                break;
            case AsyncStatus.Error:
                tcs.TrySetException(operation.ErrorCode);
                break;
            case AsyncStatus.Canceled:
                tcs.SetCanceled();
                break;

        }
    };

    return tcs.Task;
}

... but it's the same if I used the AsTask() defined in System.Runtime.WindowsRuntime.

Upvotes: 0

Views: 99

Answers (1)

Ivan Petrov
Ivan Petrov

Reputation: 4915

Seems like the call to GetGattServicesAsync hangs on your tablet. I think this is unrelated to your AsTask implementation. It simply doesn't come to it. Nor does it arrive at the if and Task.WhenAny for that matter.

You can try to replace

var task = bleDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached).AsTask();

with

var task = Task.Run(async() => await bleDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached).AsTask());

to test that the Task.Delay works.

But why GetGattServicesAsync hangs is the real question - there are a lot of questions on SO regarding it - not many with answers:

Upvotes: 4

Related Questions