2014-01-23 59 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位整數。顯然不是問題的關鍵。如果在相同的毫秒內調用,新的Random()將始終返回相同的隨機數。同步對_dictionary的訪問。 – usr

回答

2

方法不要async/await使用Task構造。

在這種情況下,要使用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,在其他地方不應使用async voidGenerateAll()方法應該是async Task,你應該從你的事件處理程序中獲得await它應該是async void