Вопрос

The current problem I'm experiencing, is the when the button is pressed, it seems nothing is happening. I'm unsure of why this happens.

Here is the on click method for the button to be pressed:

private void computeStart_Click(object sender, EventArgs e)
{
    _computeTokenSource = new CancellationTokenSource();
    GenerateAll(_computeTokenSource.Token);
}

Here is the method called by the on click.

private async void GenerateAll(CancellationToken token)
{
    await new Task(() =>
    {
        var total = (long) Math.Pow(36, 6);
        var options = new ParallelOptions {CancellationToken = token};
        Parallel.For(0, total, options, a => GenerateCodeAndHash());
    }, TaskCreationOptions.LongRunning);
}

Finally this is method called in the Parallel.For

private void GenerateCodeAndHash()
{
    var result = new string(
        Enumerable.Repeat(Chars, 6)
            .Select(s => s[new Random().Next(s.Length)])
            .ToArray());
    if (_dictionary.ContainsKey(result)) return;
    var hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(result));
    var sb = new StringBuilder();
    for (var j = 0; j < 2; j++)
        sb.Append(hash[j].ToString("x2"));
    _dictionary.TryAdd(result, sb.ToString());
}
Это было полезно?

Решение

Do not use the Task constructor with async/await.

In this case, you want to use Task.Run:

private async void computeStart_Click(object sender, EventArgs e)
{
  _computeTokenSource = new CancellationTokenSource();
  await Task.Run(() => GenerateAll(_computeTokenSource.Token));
}

private void GenerateAll(CancellationToken token)
{
  var total = (long) Math.Pow(36, 6);
  var options = new ParallelOptions {CancellationToken = token};
  Parallel.For(0, total, options, a => GenerateCodeAndHash());
}

For more information, see my async/await intro.

Другие советы

The Task constructor creates a Task that is not started. If you want to use it, you need to call Start() afterwards. But most of the time, you want to create and start the Task at the same time, which you can do using Task.Run().

Also, as pointed out by others, you should use async void only in event handlers, nowhere else; the GenerateAll() method should be async Task and you should await it from your event handler, which should be async void.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top