async/await does not work properly

时间:2018-05-06 17:08:00

标签: c# asynchronous async-await

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.

The GUI freezes when I have the following.

function Multiply(arg) {
  // calcumate the multiplication result
  var res = (this.value || 1) * arg,
    // bind this argument as an object which contains previous result
    returnFn = Multiply.bind({
      value: res
    })

  // overwrite toString method to return the current result
  returnFn.toString = function() {
    return res;
  }

  // return the function 
  return returnFn;
}


console.log(Multiply(5)(5)(6)(8));

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 When I tried to change

github-notifier

With simple 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; } method. The GUI doesn't freeze at all!

3 个答案:

答案 0 :(得分:6)

Avoid php7.0.12 except for async event handlers, plus you can use instantclient_12_2 and make code async all the way through.

async void

An example of calling ReadToEndAsync within the button click event handler, as implied by the comment from original post

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

private async Task<string> GetTextAsync(string s) {
    string textToReturn = "Hello";
    using (StreamReader sr = new StreamReader(File.OpenRead(s))) {
        textToReturn = await sr.ReadToEndAsync();
    }
    return textToReturn;
}

You should also put a SetUpTextBox around everything with the an async void event handler, otherwise any exceptions will go unobserved.

Reference Async/Await - Best Practices in Asynchronous Programming

答案 1 :(得分:1)

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

  • 使用ReadToEndAsync
  • 当任务不受CPU限制时,避免Task.Run
  • 当方法不是事件处理程序时,避免async void
  • 进行适当的错误处理。

Nkosi做了很好的工作,说明了这一点。

剩下的就是解释为什么Thread.Sleep(2500)不会阻止用户界面。

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

您可以在System.Threading.Thread.CurrentThread.IsThreadPoolThread内验证GetText是否为真(例如,您可以设置断点并使用检查进行检查)。

这意味着无法在GetText内阻止UI线程,因为UI线程不会运行GetText

但为什么然后Thread.Sleep(2500);产生不同的结果呢?

嗯......有什么区别:

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线程,而是未处理,并且使应用程序崩溃(编辑:我测试过)。
  • 执行所需的时间。但是,由于此代码不会阻止用户界面 - 因为它在ThreadPool中运行 - 这也不是。
  • 返回的文本数量。
  

当你消除了不可能的事物时,无论多么不可能,遗体都必须是真理

- 夏洛克·福尔摩斯

因为你要回复太多文字而导致用户界面停滞不前。

让我这样说......

返回太多文字

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;,忙着尝试渲染从文件中获取的所有文本。 或者至少这是我的假设。

答案 2 :(得分:-3)

Create an async void (for exemple Wait) with Thread.Sleep(x) inside and call it with "await Wait(x) ;" inside an async void.