0

我目前正在为 Windows Store 编写 C# 应用程序。

我有 Cache 类、News UserControl 类和 MainPage 类

我在 MainPage 构造函数 Cache 类中调用,然后为 News 类调用 InitializeData,在该类中我使用来自 Cache 的数据,但是有问题,在 Cache 构造函数中我接收数据但他没有执行整个函数,他在第三个从 Cache 构造函数切换到 InitializeData等待功能。

主页:

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)
        {

        }
    }

这有可能做到吗?任何想法谢谢!

4

2 回答 2

2

Stephen Cleary 关于async和构造函数的文章描述了如何进行这项工作。

在您的情况下,我认为工厂模式(如 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's的末尾启用按钮或类似的东西InitializeAsync()

于 2013-04-20T17:32:21.523 回答
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);
}

这是假设您真的,真的不能在没有完全初始化缓存的情况下创建主页。如果你处理它(例如,在完成初始化之前显示类似“正在加载...”的状态),那会更好。

于 2013-04-20T15:31:59.593 回答