基本TPL-运行异步代码时应用程序挂起

时间:2018-08-09 11:16:42

标签: async-await task-parallel-library

我希望这将是一个简单的问题,因为我对TPL还是很陌生,尽管非常愿意学习。

我已经构建了一个基本的WPF应用,该应用会生成随机数并对其进行哈希处理,并且会继续执行此操作,直到满足特定条件为止(最后一个数字生成的哈希以用户指定的最后一个字符结尾,例如“ 37f”或“ 1f5e”)。

虽然我认为我已经设法解决了异步问题,但除非在运行随机数的方法中引入Thread.Sleep持续10ms,否则应用程序在运行期间仍然会明显挂起一小段,如下所示。我无法弄清楚为什么会发生这种情况,因为生成器还是在UI线程之外...

private void ButtonBase2_OnClick(object sender, RoutedEventArgs e)
{
if (string.Equals(CommandButton2.Content.ToString(), "Start")) //we're checking the state in which the action button is: Start or Stop
  {
    _cts2 = new CancellationTokenSource(); // create a new cancellation token source
    var token = _cts2.Token; // assign it a new token
    CommandButton2.Content = "Stop"; // change the button state to stop
    var lastDigits = InputConstraint2.Text; // read constraint

    Task.Run(() => ContinuationMethod(lastDigits, false, token), token)
               .ContinueWith((t) => { CommandButton2.Content = "Start"; }, 
               TaskScheduler.FromCurrentSynchronizationContext());
  } 
else
  {
    _cts2.Cancel();
    CommandButton2.Content = "Start"; // reset the button to start
  }
}


private void ContinuationMethod(string lastDigits, bool check, CancellationToken token)
{
  var random = new Random();
  while (!check)
    {
      try
      {
      if (token.IsCancellationRequested)
                {token.ThrowIfCancellationRequested();} 
      }
      catch (OperationCanceledException e)
      {
      break;
      }

      var tuple = FindHashContinuation(lastDigits, random); 
      Dispatcher.Invoke(() => // call the dispatcher to switch the execution on the UI thread
            {
             Debug.WriteLine(tuple.Item1);
             TrialHash2.Text = tuple.Item1;
             TrialNumber2.Text = 
                tuple.Item2.ToString(CultureInfo.InvariantCulture);
            });
            check = tuple.Item3;
   }

来了。 Thread.Sleep在下面。

 private Tuple<string, double, bool> FindHashContinuation(string lastDigits, Random random)
    {
        Thread.Sleep(10); //!!! This is what maintains the async behaviour in the app
        bool check = false;
        double newNo = random.Next();
        byte[] bytes = Encoding.UTF8.GetBytes(newNo.ToString(CultureInfo.InvariantCulture));
        var hashstring = new SHA1Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        var hashString = hash.Aggregate("",
            (newstring, newbyte) => newstring + $"{newbyte:x2}");
        if (hashString.EndsWith(lastDigits))
        {
            check = true;
        }
        return new Tuple<string, double, bool>(hashString, newNo, check); // hash, actualNumber and check
    }

知道为什么需要该thread.sleep吗?

感谢您的答复。

Dragos

0 个答案:

没有答案