Reputation: 43523
In my windows 8 application there is a global class where there are a few static properties like:
public class EnvironmentEx
{
public static User CurrentUser { get; set; }
//and some other static properties
//notice this one
public static StorageFolder AppRootFolder
{
get
{
return KnownFolders.DocumentsLibrary
.CreateFolderAsync("theApp", CreationCollisionOption.OpenIfExists)
.GetResults();
}
}
}
You can see I want to use the application root folder somewhere else in the project, so I make it a static property. Inside the getter, I need to make sure the root folder exists,otherwise create it. But the CreateFolderAsync
is an async method, here I need a synchronized operation. I tried GetResults()
but it throws an InvalidOperationException
. What is the correct implementation? (The package.appmanifest is correctly configured, the folder is actually created.)
Upvotes: 7
Views: 25814
Reputation: 456447
I suggest you use asynchronous lazy initialization.
public static readonly AsyncLazy<StorageFolder> AppRootFolder =
new AsyncLazy<StorageFolder>(() =>
{
return KnownFolders.DocumentsLibrary
.CreateFolderAsync("theApp", CreationCollisionOption.OpenIfExists)
.AsTask();
});
You can then await
it directly:
var rootFolder = await EnvironmentEx.AppRootFolder;
Upvotes: 17
Reputation: 12849
Good solution: Don't make a property. Make an async method.
"I hate await, how can I make everything synchronous?" solution: How to call asynchronous method from synchronous method in C#?
Upvotes: 15
Reputation: 2561
Here is an idea.
public Task<int> Prop {
get
{
Func<Task<int>> f = async () =>
{
await Task.Delay(1000); return 0;
};
return f();
}
}
private async void Test()
{
await this.Prop;
}
but it creates a new Func object for every call this would do the same
public Task<int> Prop {
get
{
return Task.Delay(1000).ContinueWith((task)=>0);
}
}
You can't await a set since await a.Prop = 1;
is not allowed
Upvotes: 0
Reputation: 2666
use the await keyword
public async static StorageFolder GetAppRootFolder()
{
return await ApplicationData
.LocalFolder
.CreateFolderAsync("folderName");
}
and in your code
var myRootFolder = await StaticClass.GetAppRootFolder(); // this is a synchronous call as we are calling await immediately and will return the StorageFolder.
Upvotes: 4