附加到先前启动的异步进程

问题描述 投票:0回答:1

所以我有一个使用令牌为用户工作的应用程序。用户只能在1台设备上登录(登录之前的令牌过期后)。所以我提出了缓存一些数据的想法。所以我创建了一个单例的CacheManager。

CacheManager有一个包含先前获取的数据的Dictionary。

所以这是一个例子:

/// <summary>
/// Tries to get Global settings data from the cache. If it is not present - asks ServiceManager to fetch it.
/// </summary>
/// <returns>Global setting object</returns>
public async Task<GlobalSettingsModel> GetGlobalSettingAsync()
{
    GlobalSettingsModel result;

    if (!this.cache.ContainsKey("GlobalSettings"))
    {
        result = await ServiceManager.Instance.RequestGlobalSettingAsync();
        if (result != null)
        {
            this.cache.Add("GlobalSettings", result);
        }

        // TODO: Figure out what to do in case of null
    }

    return (GlobalSettingsModel)this.cache["GlobalSettings"];
}

所以问题是,如何修改此方法,以处理此类情况:

例如,我从服务器调用的方法比导航到需要数据的页面的用户工作时间更长我想显示加载指示符并在实际收到数据时隐藏它。

为什么我需要它,我们有2页 - ExtendedSplashScreen和UpdatesPage用户可以快速跳过它们(1s)或留下来阅读有趣的信息(比方说1m)。在这段时间里,我已经开始获取GetGlobalSetting,以便在进入LoginPage时让进程结束或下载至少一些内容(以缩小用户的等待时间)。

在我推出的ExtendedSplashScreen上:

CacheManager.Instance.GetGlobalSettingAsync();

出于测试目的,我修改了ServiceManager方法:

/// <summary>
/// Fetches the object of Global Settings from the server
/// </summary>
/// <returns>Global setting object</returns>
public async Task<GlobalSettingsModel> RequestGlobalSettingAsync()
{
    await Task.Delay(60000);

    // Request and response JSONs are here, because we will need them to be logged if any unexpected exceptions will occur

    // Response JSON
    string responseData = string.Empty;

    // Request JSON
    string requestData = JsonConvert.SerializeObject(new GlobalSettingsRequestModel());

    // Posting list of keys that we want to get from GlobalSettings table
    HttpResponseMessage response = await client.PostAsync("ServerMethod", new StringContent(requestData, Encoding.UTF8, "application/json"));

    // TODO: HANDLE ALL THE SERVER POSSIBLE ERRORS

    Stream receiveStream = await response.Content.ReadAsStreamAsync();
    StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);

    // Read the response data
    responseData = readStream.ReadToEnd();

    return JsonConvert.DeserializeObject<GlobalSettingsResponseModel>(responseData).GlobalSettings;
}

因此,当用户访问LoginPage时,我执行以下操作:

// The await is here because there is no way without this data further
GlobalSettingsModel settings = await CacheManager.Instance.GetGlobalSettingAsync();

在这里,如果已经下载了数据,我想从缓存中获取数据,或者一旦完成下载,CacheManager就会将数据返回给我。

c# async-await
1个回答
0
投票

一种方法是缓存Task<GlobalSettingsModel>而不是GlobalSettingsModel本身。从缓存中获取它时,您可以检查它是否已完成,然后等待或相应地使用其结果。

© www.soinside.com 2019 - 2024. All rights reserved.