C# 如何做到整体功能不只是一半?

C# 如何做到整体功能不只是一半?,c#,asynchronous,microsoft-metro,async-await,C#,Asynchronous,Microsoft Metro,Async Await,我目前正在为Windows应用商店编写C#应用程序 我有Cache类、News UserControl类和MainPage类 我正在调用MainPage构造函数缓存类,然后为News类调用InitializeData,我使用缓存中的数据,但有一个问题,在缓存构造函数中我接收数据,但他没有完成整个函数,他在第三个等待函数中从缓存构造函数切换到InitializeData 主页: public MainPage() { this.InitializeComponent(); Cac

我目前正在为Windows应用商店编写C#应用程序

我有Cache类、News UserControl类和MainPage类

我正在调用MainPage构造函数缓存类,然后为News类调用InitializeData,我使用缓存中的数据,但有一个问题,在缓存构造函数中我接收数据,但他没有完成整个函数,他在第三个等待函数中从缓存构造函数切换到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)
        {

        }
    }

这可能做到吗?如果有任何想法,谢谢

基本上,当您调用异步方法并且从不等待它完成时,就会发生这种情况

异步方法的全部要点是不阻塞。。。而且构造函数本身不能是异步的

一个选项是编写异步静态方法来创建缓存:

static async Task<Cache> CreateCache()
{
    // Change your InitializeData to return the data which the cache needs
    var data = await InitializeData();
    return new Cache(data);
}

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

这就是当您调用异步方法并且从不等待它完成时发生的情况

异步方法的全部要点是不阻塞。。。而且构造函数本身不能是异步的

一个选项是编写异步静态方法来创建缓存:

static async Task<Cache> CreateCache()
{
    // Change your InitializeData to return the data which the cache needs
    var data = await InitializeData();
    return new Cache(data);
}
这是假设你真的,真的不能让主页在缓存没有完全初始化的情况下被创建。如果您可以处理该问题(例如,在完成初始化之前显示类似“加载…”的状态),则效果会更好。

介绍了如何进行此操作

在您的情况下,我认为工厂模式(如Jon的回答中所建议的)不适用于
MainPage
,因为它是一个GUI组件。但是第二种方法,异步初始化模式,将起作用

您已经为
缓存
实现了该模式,现在还需要为
主页
实现它:

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
和add
在初始化开始时等待此操作。此外,您可能希望启用按钮或类似于
MainPage
InitializeAsync()

介绍了如何实现这一点

在您的情况下,我认为工厂模式(如Jon的回答中所建议的)不适用于
MainPage
,因为它是一个GUI组件。但是第二种方法,异步初始化模式,将起作用

您已经为
缓存
实现了该模式,现在还需要为
主页
实现它:

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
和add
在初始化开始时等待此操作。此外,您可能希望启用
MainPage
InitializeAsync()

末尾的按钮或类似的东西。似乎设计
缓存的人都理解异步初始化应该如何工作。你…吗?如果没有,请阅读。那么为什么您有没有实际使用的
初始化
属性?但它在构造函数中使用了函数Init,我为metro编程了大约3天,它与基本C#完全不同。是的,您设置了属性,但从未使用过它的值。这意味着您可能会完全删除它。好的,那么如何在主页构造函数中使用它呢?因为它是异步的,所以它需要一些代码,这是我不知道的。看来设计
Cache
类的人都明白异步初始化应该如何工作。你…吗?如果没有,请阅读。那么为什么您有没有实际使用的
初始化
属性?但它在构造函数中使用了函数Init,我为metro编程了大约3天,它与基本C#完全不同。是的,您设置了属性,但从未使用过它的值。这意味着您可能会完全删除它。好的,那么如何在主页构造函数中使用它呢?因为它是异步的,所以它需要一些代码,这就是我不知道的,当创建
MainPage
时,你会如何调用它?所以我应该在MainPage的构造函数中调用CreateMainPage?并将所有内容从缓存构造函数移动到函数CreateCache?@user1085907:否,CreateMainPage调用MainPage构造函数。你不能编写异步构造函数,你需要开始更加异步地思考。当创建
MainPage
时,你会如何调用它?所以我应该在MainPage的构造函数中调用CreateMainPage?并将所有内容从缓存构造函数移动到函数CreateCache?@user1085907:否,CreateMainPage调用MainPage构造函数。您不能编写异步构造函数,您需要开始更加异步地思考。