我希望这将是一个简单的问题,因为我对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