异步/等待无法正常工作 [英] async/await does not work properly

查看:78
本文介绍了异步/等待无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的异步/等待方法有问题.我是异步/等待新手,似乎无法正常工作.

I have problem with async/await method of mine. I am new into async/await and seems I can't get it to work correctly.

当我遇到以下情况时,GUI冻结.

The GUI freezes when I have the following.

private async void SetUpTextBox(string s)
{
    //This method is called in button event
    string textToSet = await GetTextA(s);
    read_Box.Text = textToSet;
}

private Task<string> GetTextA(string s)
{
    return Task.Run(() => GetText(s));
}

private string GetText(string s)
{
    string textToReturn = "Hello";
    using (StreamReader sr = new StreamReader(File.OpenRead(s)))
    {
        textToReturn = sr.ReadToEnd();
    }
    return textToReturn;
}

我不知道我在做什么错.我知道我对此很陌生,这就是为什么我在这里学习(又称不要判断!).

I don't know what I am doing wrong. I know I am new into this and that's why I am here to learn (a.k.a don't judge!).

P.S,当我尝试更改

P.S When I tried to change

using (StreamReader sr = new StreamReader(File.OpenRead(s)))
{
    textToReturn = sr.ReadToEnd();
}

使用简单的Thread.Sleep(2500)方法. GUI根本不会冻结!

With simple Thread.Sleep(2500) method. The GUI doesn't freeze at all!

推荐答案

首先,您应该做的事情不是:

First off, the things you should do, that you aren't:

  • 使用ReadToEndAsync.
  • 当任务不受CPU限制时避免使用Task.Run.
  • 当方法不是事件处理程序时避免使用async void.
  • 具有正确的错误处理.
  • Using ReadToEndAsync.
  • Avoiding Task.Run when the task is not CPU bound.
  • Avoiding async void when the method is not an event handler.
  • Having proper error handling.

恩科西(Nkosi)做得很好,说明了这一点.

Nkosi has done a decent job illustrating that.

剩下的内容是解释为什么Thread.Sleep(2500)不阻止UI.

What is left is explaining why Thread.Sleep(2500) does not block the UI.

首先,请注意Task.Run将使用ThreadPool运行任务.

First off, notice that Task.Run will be running the task using the ThreadPool.

您可以验证System.Threading.Thread.CurrentThread.IsThreadPoolThreadGetText内部是否正确(例如,您可以设置断点并使用检查进行检查).

You can verify that System.Threading.Thread.CurrentThread.IsThreadPoolThread is true inside of GetText (for example, you can set a break point and use inspections to check).

这意味着该UI线程无法在GetText内部被阻止,因为该UI线程未运行GetText.

That means that the UI thread cannot be blocked inside of GetText, because the UI thread does not run GetText.

但是为什么Thread.Sleep(2500);会产生不同的结果?

But why then Thread.Sleep(2500); yields a different result?

嗯...之间有什么区别

Hmmm... what is the difference between:

private string GetText(string s)
{
    string textToReturn = "Hello";
    using (StreamReader sr = new StreamReader(File.OpenRead(s)))
    {
        textToReturn = sr.ReadToEnd();
    }
    return textToReturn;
}

并且:

private string GetText(string s)
{
    string textToReturn = "Hello";
    Thread.Sleep(2500);
    return textToReturn;
}

让我告诉你:

  • 可能引发的异常.由于您没有处理它们-并且我假设您正在调试器中使用调试版本-您会注意到的.因此,我认为这不是问题.即使不是,异常也不来自UI线程,它将无法处理,并导致应用程序崩溃(我测试过).
  • 执行所花费的时间.但是,由于UI不会被此代码阻止-在ThreadPool中运行-也不是.
  • 返回的文本量.
  • The possible exceptions thrown. Since you are not handling them - and I assume you are using a debug build in a debugger - you would have noticed. So, I do not think this is the problem. Even if you weren't, the exceptions are not from the UI thread, would go unhandled, and crash the application ( I tested).
  • The ammount of time it takes to execute. However, since the UI will not be blocked by this code - being it running in the ThreadPool - that is not it either.
  • The ammount of text returned.

当您消除了不可能的事物之后,无论多么不可能的一切,剩下的都是真理

When you have eliminated the impossible, whatever remains, however improbable, must be the truth

-夏洛克·福尔摩斯

由于返回的文本过多,UI被卡住了.

The UI is being stuck because you are returning too much text.

让我这样说吧...

返回的文本过多

private string GetText(string s)
{
    string textToReturn = "Hello";
    using (StreamReader sr = new StreamReader(File.OpenRead(s)))
    {
        textToReturn = sr.ReadToEnd();
    }
    return textToReturn;
}

返回了一些文字:

private string GetText(string s)
{
    string textToReturn = "Hello";
    Thread.Sleep(2500);
    return textToReturn;
}


因此,UI被卡在read_Box.Text = textToSet;上,正忙于呈现从文件中获取的所有文本. 或者至少这是我的假设.


The UI, is therefore being stuck at read_Box.Text = textToSet;, busy trying to render all the text that you got from the file. Or at least that is my hyphothesis.

这篇关于异步/等待无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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