Reputation: 757
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?
Upvotes: 3
Views: 2181
Reputation: 58980
You have to make the return type of CreateOrInitializeMainXml
a Task
and await
the Task
in the event handler, which also must be async
:
So, change your method declaration:
private async Task CreateOrInitializeMainXml() { ... }
And the consuming code:
var isCreateFileSuccessfull = await CreateOrInitializeMainXml();
The general rule for async void
is that you should only use it for event handlers. async void
is "fire-and-forget": you cannot await it, and exceptions thrown in async void
methods may be uncatchable and crash your application.
The async
keyword has been described as "viral" -- when you start using it, it will spread through your application as more and more things become async
in order to await
other async
methods. This is perfectly natural and fine. Don't fight it.
Upvotes: 6