Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async method won't return when called

I'm having a bad time with this. I'm trying to make a async method that returns the contents of a local file as string. This is my approach:

private static async Task<string> ReadContentsAsString(string fileName)
{
    var uri = new Uri(string.Format(@"ms-appx:///{0}", fileName));
    var file = await StorageFile.GetFileFromApplicationUriAsync(uri).AsTask().ConfigureAwait(false);
    var stream = await file.OpenStreamForReadAsync().ConfigureAwait(false);

    using (var streamReader = new StreamReader(stream))
    {                
        return await streamReader.ReadToEndAsync();
    }
 }

Unfortunately, after the execution reaches the end of my method, the application waits forever. It hangs completely. It's being called at the very beginning, when the splash screen still shows (Windows Phone 8.1)

What do I miss?

like image 786
SuperJMN Avatar asked Apr 09 '26 09:04

SuperJMN


2 Answers

I suspect that further up your call stack, your code has a call to Task.Wait or Task<T>.Result. This can cause a deadlock that I describe on my blog.

In summary, what happens is that when await is used on a task, by default it will capture the current "context" and use that context to resume the async method. In this case, the context is the UI context, which is associated with the single UI thread. If code further up the call stack is calling Wait or Result, then it's blocking the UI thread, which prevents the async method from finishing.

like image 173
Stephen Cleary Avatar answered Apr 12 '26 00:04

Stephen Cleary


Your method is working as it should. I suspect that you are encountering this issue while debugging.

I also have noticed (sometimes) such a behaviour when debugging asyc method (here is a link to the question) - the program never returns from the method and just hangs - I don't know the exact reason of this. To test it just try to run your method like this - for example upon button click:

private async void firstBtn_Click(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("Before method");
    string readValue = await ReadContentsAsString("TextFile1.txt");
    Debug.WriteLine(string.Format("Read value: {0}", readValue));
}

As I've tested on device - it should work, but if I set a breakpoint inside your method - it will hang.

like image 25
Romasz Avatar answered Apr 12 '26 00:04

Romasz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!