我目前正在为Windows Store编写C#应用程序。
我有Cache类,News UserControl类和MainPage类
我正在调用MainPage构造函数Cache类,然后调用InitializeData for News类,其中我使用来自Cache的数据,但是有问题,在Cache构造函数中我接收数据但是他没有做整个函数,他从Cache构造函数切换到第三个的InitializeData等待函数。
的MainPage:
public MainPage()
{
this.InitializeComponent();
Cache.Cache cache = new Cache.Cache();
NewsContent.InitializeData(cache.MyData);
}
高速缓存:
public Cache()
{
Initialization = Init();
}
public Task Initialization
{
get;
private set;
}
private async Task Init()
{
try
{
cS = await folder.CreateFileAsync("cache.txt", CreationCollisionOption.OpenIfExists);
cS_titles = await folder.CreateFileAsync("titles_cache.txt", CreationCollisionOption.OpenIfExists);
string contentOfFile = await FileIO.ReadTextAsync(cS);
int contentLength = contentOfFile.Length;
if (contentLength == 0) // download data for first using
{
await debug.Write("Is empty!");
//.......
// ....
await FileIO.AppendTextAsync(cS, file_content);
await FileIO.AppendTextAsync(cS_titles, file_content_titles);
}
else // check for same data, if isnt same download new, else nothing
{
await debug.Write(String.Format("Isnt empty. Is long: {0}", contentLength)); // here he break and continue to NewsContent.InitializeData(cache.MyData);
// ....
// ....
}
await MyFunction(); // i need get constructor to this point then he will do NewsContent.InitializeData(cache.MyData);
}
catch (Exception)
{
}
}
这可能吗?对于任何想法,谢谢!
答案 0 :(得分:2)
当您调用异步方法并且从不等待它完成时,会发生这种情况。
异步方法的重点是你不阻止...而你的构造函数本身不能是异步的。
一种选择是编写异步静态方法来创建缓存:
static async Task<Cache> CreateCache()
{
// Change your InitializeData to return the data which the cache needs
var data = await InitializeData();
return new Cache(data);
}
从根本上说,你仍然需要任何调用CreateCache来理解它是异步发生的。您不希望阻止UI线程等待全部初始化。
编辑:我没有发现这是从MainPage
构造函数调用的。您可能会再次应用相同的方法:
public static async Task<MainPage> CreateMainPage()
{
var cache = await Cache.CreateCache();
return new MainPage(cache);
}
这假设您确实无法在没有完全初始化缓存的情况下创建主页面。如果可以处理(例如显示“Loading ...”状态,直到它完成初始化),那就更好了。
答案 1 :(得分:2)
Stephen Cleary's article on async
and constructors介绍了如何使其发挥作用。
在您的情况下,我认为工厂模式(如Jon的回答中所建议的)不适用于MainPage
,因为它是一个GUI组件。但第二种方法,即异步初始化模式,将起作用。
您已经为Cache
实施了该模式,现在您还需要为MainPage
实施该模式:
public MainPage()
{
Initialization = InitializeAsync();
}
public Task Initialization { get; private set; }
private async Task InitializeAsync()
{
Cache.Cache cache = new Cache.Cache();
await cache.Initialization;
NewsContent.InitializeData(cache.MyData);
}
如果MainPage
有一些事件依赖于初始化完成,那么您可以在async
处添加await this.Initialization
并在其开头添加MainPage
。此外,您可能希望在InitializeAsync()
的{{1}}末尾启用此类按钮或类似内容。