2014-01-23 3 views
0

Текущая проблема, с которой я столкнулся, - это когда нажата кнопка, кажется, ничего не происходит. Я не знаю, почему это происходит.Задача не работает?

Вот по щелчку метод кнопка будет нажата:

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

Вот метод вызывается по щелчку.

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); 
} 

Наконец это метод вызывается в 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()); 
} 
+0

Вы проверяли, что страница загружается или нет. Если событие Page_Load уволено, тогда, пожалуйста, покажите исходный код. –

+0

@GovindaRajbhar Это не страница, это форма окон. Я должен был указать это. – shredder8910

+1

'Math.Pow (36, 6)' переполняет 64-битное целое число. Разумеется, дело не в этом. 'new Random()' всегда будет возвращать одно и то же случайное число, если вызывается на той же миллисекунде. Синхронизировать доступ к _dictionary. – usr

ответ

2

Не используйте Task конструктор с async/await.

В этом случае, вы хотите использовать 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()); 
} 

Для получения дополнительной информации см мой async/await intro.

+0

И лучше избавиться от возвращаемого типа 'void', хотя здесь нет никакой разницы. – usr

+0

Хороший улов; это было бы особенно важно, если бы расчет был отменен. Обновлено. –

1

Конструктор Task создает Task, который не запущен. Если вы хотите его использовать, вам нужно позвонить по телефону Start(). Но большую часть времени вы хотите создать и запустить Task в то же время, что вы можете сделать, используя Task.Run().

Также, как указано другими, вы должны использовать async void только в обработчиках событий, больше нигде; метод GenerateAll() должен быть async Task, и вы должны await его от вашего обработчика событий, который должен быть async void.

Смежные вопросы