我试图把一些旧代码同步方法为异步方法,但我遇到了一些麻烦了解 [英] I'm trying to turn a synchronous method from some old code into an asynchronous method, but I'm having some trouble understand

查看:193
本文介绍了我试图把一些旧代码同步方法为异步方法,但我遇到了一些麻烦了解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图把一些旧代码同步方法为异步方法,但我遇到了一些麻烦了解。从我所读过的视频和教程他们似乎被创建到方法,一个实际的功能,其他的包装,然后它被称为UI上的包装。

I'm trying to turn a synchronous method from some old code into an asynchronous method, but I'm having some trouble understand. From all the videos and tutorials I've read they seem to be creating to methods, one the actual function, the other a wrapper and then it's the wrapper called on the UI.

下面是我的代码:

private async Task<bool> login(String username, String password)
{
        var tcs = new TaskCompletionSource<RestSharp.IRestResponse>();

        RestSharp.RestRequest request = new RestSharp.RestRequest("/accounts/login/", RestSharp.Method.GET);
        RestSharp.IRestResponse response = client.Execute(request);

        // Make the login request
        request = new RestSharp.RestRequest("/accounts/login/", RestSharp.Method.POST);
        request.AddParameter("username", username);
        request.AddParameter("password", password);

        response = client.Execute(request);

        // Return loggin status
        dom = response.Content;
        return dom["html"].HasClass("logged-in"); 
}

有关某种原因,当我尝试调用该方法从UI线程。按一下按钮,它要求我做出按钮事件异步

For some reason when I try to call the method on the UI thread from a button click, it's asking me to make the button event async.

txtLog.AppendText("Before Await");

Task<bool> result = await login("","");

txtLog.AppendText("After Await");
txtLog.AppendText("Result: " + result.toString());



我是否需要,它也设定为异步这使得调用登录的包装方法?

Do I need a wrapper method that is also set to async which makes the call to login?

这一切似乎有点复杂。

All of this seems a little complex.

推荐答案

要先回答你的第二部分,是你需要标记按钮的事件异步,如果你想使用关键字等待在你的代码,你必须声明函数异步

To answer your 2nd part first, yes you need to mark the event for the button async, if you want to use the keyword await in your code you must declare the function async.

2ndly如果一个函数使用异步,而无需一个的await 它里面的代码不会被异步运行,您可能需要创建任务并运行它内部的同步方法或重写为异步方法。

2ndly if a function uses async without having an await inside of it the code will not be run asynchronously, you either need to create a task and run your synchronous method inside of it or rewrite the method to be asynchronous.

由于任务的方法:

private async void button1_Click(object sender, EventArgs e)
{
    txtLog.AppendText("Before Await");

    //Note I changed from "Task<bool>" to "bool", await is like calling ".Result" 
    //  on a task but not blocking the UI, so you store the type you are waiting for.
    bool result = await Task.Run(() => login("","")); //You would still use your old login code before you tried to make it async, it requires no modifications.

    txtLog.AppendText("After Await");
    txtLog.AppendText("Result: " + result.ToString());
}



重写功能的方法:

Rewriting the function method:

private async void button1_Click(object sender, EventArgs e)
{
    txtLog.AppendText("Before Await");

    //Note I changed from "Task<bool>" to "bool", await is like calling ".Result" 
    //  on a task but not blocking the UI, so you store the type you are waiting for.
    bool result = await login("",""); 

    txtLog.AppendText("After Await");
    txtLog.AppendText("Result: " + result.ToString());
}

private Task<bool> login(String username, String password)
{
    var tcs = new TaskCompletionSource<bool>();

    // Make the login request
    var request = new RestSharp.RestRequest("/accounts/login/", RestSharp.Method.POST);
    request.AddParameter("username", username);
    request.AddParameter("password", password);

    client.ExecuteAsync(request, (response, handle) =>
        {
            try
            {
                // Return loggin status
                var dom = response.Content;

                //dom["html"] did not have a .HasClass in my tests, so this code may need work.
                tcs.TrySetResult(dom["html"].HasClass("logged-in")); 
            }
            catch(Exception ex)
            {
                tcs.TrySetException(ex);
            }
        });

    return tcs.Task;
}

在我的重写方法我在做什么是我使用 ExecuteAsync 魔女IRestClient的部分。这个函数调用一个回调方法,它完成的时候,在回调方法我称之为的 TCS 的setResult 来报到结果我想要的。

In my "rewrite method" what I am doing is I am using ExecuteAsync witch is part of IRestClient. That function calls a callback method when it completes, in the callback method I call tcs's SetResult to report back the result I wanted.

您可以通过采取进一步扩大这个的CancellationToken 如果令牌升高调用中止() RestRequestAsyncHandle ,但是如果我们做到这一点,我们需要把异步回的功能和等待的结果,所以我们可以在取消标记注册后清理。

You could expand this further by taking in a CancellationToken and if the token is raised call Abort() on RestRequestAsyncHandle, however if we do this we need to bring the async back in to the function and await the result so we can clean up after the cancellation token registration.

private Task<bool> login(String username, String password)
{
    return login(username, password, CancellationToken.None);
}

private async Task<bool> login(String username, String password, CancellationToken cancelToken)
{
    var tcs = new TaskCompletionSource<bool>();

    // Make the login request
    var request = new RestSharp.RestRequest("/accounts/login/", RestSharp.Method.POST);
    request.AddParameter("username", username);
    request.AddParameter("password", password);

    var asyncHandle = client.ExecuteAsync(request, (response, handle) =>
        {
            try
            {
                // Return loggin status
                var dom = response.Content;

                tcs.TrySetResult(dom["html"].HasClass("logged-in")); 
            }
            catch(Exception ex)
            {
                tcs.TrySetException(ex);
            }
        });

    //if the token is canceled it will call `asyncHandle.Abort()` for us.
    using(cancelToken.Register(() =>
        {
           if(tcs.TrySetCanceled(cancelToken))
               asyncHandle.Abort();
        }))
    {
        return await tcs.Task;
    }
}

这篇关于我试图把一些旧代码同步方法为异步方法,但我遇到了一些麻烦了解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆