locked
call Async Method crashes

    Question

  •        

    <Page x:Class="App01.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App01" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button Content="Test01" x:Name="btnTest01" HorizontalAlignment="Left" Margin="79,72,0,0" VerticalAlignment="Top" Click="btnTest01_Click"/> </Grid> </Page>

    </page>

       public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            string str = null;
    
    
            async void fu()
            {
                StorageFolder folder =
                    Windows.Storage.ApplicationData.Current.LocalFolder;
                StorageFile sampleFile =
                    await folder.CreateFileAsync("sample01.txt", CreationCollisionOption.ReplaceExisting);
    
    
                await Windows.Storage.FileIO.WriteTextAsync(sampleFile, "this is nice");
    
                str = "abc";
    
            }
            private void btnTest01_Click(object sender, RoutedEventArgs e)
            {
                fu();
    
                int x = str.Length;  //hier it crashes, because str == null;
    
            }											
    
        }

    I call in the btnTest01 eventHandler first fu() (in this function I have an async call).

    I think when I call fu(), in fu the call waits until the Operation has finished (because await),

    And so, as Long as in fu is waiting, I think also fu is waiting, but this is wrong.

    Remark: this is a sample of the Problem, I know that I can check if str is null, but this is not the Problem.

    if I have fu();   fu02(); fu03();  etc. and fu is asnc, the program must continue after fu is READY.

    Thank you for any help.

    Rowe10

    • Edited by rowe10 Wednesday, April 01, 2015 6:43 PM
    Wednesday, April 01, 2015 6:38 PM

Answers

  • This code has two obvious issues that probably cause your error.

    Firstly, don't use async void. Async void cannot be awaited (meaning you're defeating the whole purpose of async). So change the fu() method to be 'async Task fu()'

    Secondly, you can/should use async void for an event handler (and only in an event handler). So change that to 'async void btnTest01_Click(...)'

    And await the fu() method:

    'await fu();'.

    When you make those changes, the btnTest01_Click method will run asynchronously, and therefore is able to await for the resul of the fu() method (which itself is now able to await the network access it's doing.

    I hope that makes sense.

    I'd also recommend improving your code by making fu() return the string value. I would redo your code like this:

     public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
           
            async Task<string> fu()
            {
                StorageFolder folder =
                    Windows.Storage.ApplicationData.Current.LocalFolder;
                StorageFile sampleFile =
                    await folder.CreateFileAsync("sample01.txt", CreationCollisionOption.ReplaceExisting);
    
    
                await Windows.Storage.FileIO.WriteTextAsync(sampleFile, "this is nice");
    
                return "abc";
    
            }
            private async void btnTest01_Click(object sender, RoutedEventArgs e)
            {
                int x = str.Length(await fu()); // waits for fu() to return a value
    
            }											
    
        }


    I'm a self-taught noob amateur. Please take this into account when responding to my posts or when taking advice from me.

    • Marked as answer by rowe10 Thursday, April 02, 2015 2:36 PM
    Thursday, April 02, 2015 2:05 AM

All replies

  • This code has two obvious issues that probably cause your error.

    Firstly, don't use async void. Async void cannot be awaited (meaning you're defeating the whole purpose of async). So change the fu() method to be 'async Task fu()'

    Secondly, you can/should use async void for an event handler (and only in an event handler). So change that to 'async void btnTest01_Click(...)'

    And await the fu() method:

    'await fu();'.

    When you make those changes, the btnTest01_Click method will run asynchronously, and therefore is able to await for the resul of the fu() method (which itself is now able to await the network access it's doing.

    I hope that makes sense.

    I'd also recommend improving your code by making fu() return the string value. I would redo your code like this:

     public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
           
            async Task<string> fu()
            {
                StorageFolder folder =
                    Windows.Storage.ApplicationData.Current.LocalFolder;
                StorageFile sampleFile =
                    await folder.CreateFileAsync("sample01.txt", CreationCollisionOption.ReplaceExisting);
    
    
                await Windows.Storage.FileIO.WriteTextAsync(sampleFile, "this is nice");
    
                return "abc";
    
            }
            private async void btnTest01_Click(object sender, RoutedEventArgs e)
            {
                int x = str.Length(await fu()); // waits for fu() to return a value
    
            }											
    
        }


    I'm a self-taught noob amateur. Please take this into account when responding to my posts or when taking advice from me.

    • Marked as answer by rowe10 Thursday, April 02, 2015 2:36 PM
    Thursday, April 02, 2015 2:05 AM
  • Thank you, that works.

    Rowe10

    Thursday, April 02, 2015 2:36 PM