繁体   English   中英

在异步方法和正常返回方法之间共享类变量

[英]sharing class variable between async method and normal return method

这是我的课,有一个异步方法和获取方法

class Webservice
{
    public string token;
    public async void login (string url)
    {
        Console.WriteLine(url);
        var client = new HttpClient();

        // Create the HttpContent for the form to be posted.
        string username = ConfigurationSettings.AppSettings["email"];
        string password = ConfigurationSettings.AppSettings["password"];

        var requestContent = new FormUrlEncodedContent(new[] {
                new KeyValuePair<string, string>("email", username),
                new KeyValuePair<string, string>("password", password),
        });

        // Get the response.
        HttpResponseMessage response = await client.PostAsync(url, requestContent);

        // Get the response content.
        HttpContent responseContent = response.Content;

        // Get the stream of the content.
        using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
        {
            // Write the output.
            //Console.WriteLine(await reader.ReadToEndAsync());
            token = await reader.ReadToEndAsync();

        }
    }


    public string getToken (string url)
    {
        this.login(url);
        Console.WriteLine(token);
        return token+"abc";
    }

令牌=等待reader.ReadToEndAsync(); 无法设置类变量或返回getToken之后设置,有人知道如何处理这种情况吗?

通过致电:

this.login(url);

您正在触发并忘记了异步调用。

您需要使包含函数异步并等待login调用完成

public async Task<string> getToken (string url)
{
    await this.login(url);
    Console.WriteLine(token);
    return token+"abc";
}

不要使用this.login(url).Wait()

最后

public async void login (string url)

async void用于事件处理程序,应该是这样的:

public async Task login (string url)

恕我直言

我相信这堂课的职责太多了。 它不应该用于检索和存储令牌。 可以假设您的应用程序中有某种缓存层(可能只是内存)。

因此,我更喜欢这样的逻辑:

if (string.IsNullOrWhiteSpace(this.cache[TOKEN_KEY])) {
   this.cache[TOKEN_KEY] = await this.webservice.login(url);
}

// use the this.cache[TOKEN_KEY] here...
await this.anotherService.MakeRequest(this.cache[TOKEN_KEY]);

cache可能只是带有字典的单例类。

现在,新的Task<string> login(string url)方法将在底部返回令牌,而不仅仅是设置私有字段:

return await responseContent.ReadAsStringAsync();

如果需要,这种逻辑将使您更轻松地在登录名中及其周围添加层,而又无需使代码难以推理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM