Wait for Async method to complete

Refresh

November 2018

Views

1.9k time

2

I am creating a windows phone app, where on launch of the app, I create an xml in installation location of the app and then I call a method, which initializes the User settings class with the values in xml. In the beginning, I check if the xml is already available, if it is not, I create an xml, if it is present, it is read and User settings are initialized. Here is the code in OnLaunched event of App.xaml.cs

var isCreateFileSuccessfull = CreateOrInitializeMainXml();

UserSettings.GetInstance().GetValuesFromXmlDoc(HASHNOTESDOC);

where HASHNOTESDOC is of type XDocument.

The body of the method is as:

async private void CreateOrInitializeMainXml()
    {
        try 
        { 
            StorageFolder InstallationFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
            string hashnotesFile = @"Assets\hashnotes.xml";

            StorageFile file = await InstallationFolder.GetFileAsync("hashnotes.xml");
            bool fileExists = await FileExists(InstallationFolder, "hashnotes.xml");

            if (!fileExists)
            {
                await file.CopyAsync(InstallationFolder);
            }

            StorageFile hashNoteXml = await InstallationFolder.GetFileAsync(hashnotesFile);
            Stream hashNotesStream = await hashNoteXml.OpenStreamForWriteAsync();
            hashNotesXDocument = XDocument.Load(hashNotesStream);

            hashNotesXDocument.Save(hashNotesStream);

        }
        catch
        {

        }
    }

Problem is that, since the above method is an async method, even before it finishes, control tries to execute the line

UserSettings.GetInstance().GetValuesFromXmlDoc(HASHNOTESDOC);

and by this time HASHNOTESDOC is null. How can I wait till the HASHNOTESDOC is initialized and only then go and read the user settings?

1 answers

6

Вы должны сделать тип возврата и в обработчик событий, который также должен быть :CreateOrInitializeMainXmlTaskawaitTaskasync

Таким образом, изменить объявление метода:

private async Task CreateOrInitializeMainXml() { ... }

И потребляя код:

var isCreateFileSuccessfull = await CreateOrInitializeMainXml();

Общее правило в async voidтом , что вы должны использовать его только для обработчиков событий . async voidэто «огонь и забыть» , вы не можете ждать, и исключения , брошенные в async voidметодах может быть неуловимым и сбою приложения.

asyncКлючевое слово было описано как «вирусный» - когда вы начнете использовать его, он будет распространяться через приложение , как все больше и больше вещей становится asyncдля того , чтобы awaitдругие asyncметоды. Это вполне естественно и нормально. Не сопротивляйся.