我遇到的当前问题是,当按下按钮时,似乎什么也没发生。我不确定为什么会这样。
以下是按下按钮的点击方法:
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 :(得分: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。
答案 1 :(得分:1)
Task
构造函数创建一个未启动的Task
。如果您想使用它,则需要在之后致电Start()
。但大多数情况下,您希望同时创建并启动Task
,您可以使用Task.Run()
执行此操作。
另外,正如其他人所指出的,你应该只在事件处理程序中使用async void
,而不是其他地方; GenerateAll()
方法应该是async Task
,您应该await
来自您的事件处理程序,它应该是async void
。