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

时间:2018-09-06 09:19:26

标签: c# async-await

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

CacheManager的字典中包含以前提取的数据。

这是一个例子:

/// <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将在完成下载后立即将数据返回给我。

1 个答案:

答案 0 :(得分:0)

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