【问题标题】:Task not running?任务没有运行?
【发布时间】:2014-01-23 22:44:03
【问题描述】:

我遇到的当前问题是按下按钮时,似乎什么也没发生。我不确定为什么会这样。

这是要按下的按钮的点击方法:

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

【问题讨论】:

  • 您是否检查过该页面是否正在加载。如果 Page_Load 事件被触发,请显示您的源代码。
  • @GovindaRajbhar 这不是页面,而是 Windows 窗体。我应该指定的。
  • Math.Pow(36, 6) 将溢出一个 64 位整数。显然不是问题的重点。 new Random() 如果在同一毫秒内调用,将始终返回相同的随机数。同步访问_dictionary。

标签: .net-4.0 task-parallel-library c#-5.0


【解决方案1】:

不要将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

【讨论】:

  • 最好也去掉 void 返回类型,尽管在这里没有区别。
  • 好收获;如果取消计算,这一点尤其重要。已更新。
【解决方案2】:

Task 构造函数创建一个未启动的Task。如果您想使用它,您需要在之后致电Start()。但大多数时候,您希望同时创建和启动Task,您可以使用Task.Run()

另外,正如其他人所指出的,您应该只在事件处理程序中使用async void,不要在其他地方使用; GenerateAll() 方法应该是 async Task 并且你应该从你的事件处理程序中 await 它应该是 async void

【讨论】:

    猜你喜欢
    • 2015-12-29
    • 1970-01-01
    • 2012-11-21
    • 2015-03-12
    • 1970-01-01
    • 2019-12-17
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多