并行forEach搜索文件

Dix*_*Dix 2 c# winforms async-await parallel.foreach

我有一个包含2个列表框的程序,这个程序是基于搜索文件,然后比较StopWatch使用AsyncAwait和TPL 的区别...第一个列表框使用的功能 AsyncAwait(我不知道它是否更好的方式但它有效,请参阅下面的代码)

private async void button1_Click(object sender, EventArgs e)
{
    Stopwatch stopWatch = new Stopwatch();
    foreach (string d in Directory.GetDirectories(@"C:\Visual Studio Projectes\Hash\AsyncAwait\Carpetes"))
    {    
        foreach (string s in Directory.GetFiles(d))
        {
            stopWatch.Start();
            listBox1.Items.Add(s);
            await Task.Delay(1);
            btIniciar1.Enabled = false;
        }
    }
    btIniciar1.Enabled = true;
    stopWatch.Stop();
    TimeSpan ts = stopWatch.Elapsed;
    textBox1.Text = ts.ToString("mm\\:ss\\.ff") + (" minuts");
}
Run Code Online (Sandbox Code Playgroud)

然后在我的第二个列表框在那里我坚持,我不知道如何实现Parallel.ForEach对像async,有什么更好的方式来做到这一点?在这种情况下我找不到使用TPL的方法和我的第一个列表框一样,你能帮帮我吗?

Ste*_*ary 6

async在您的示例代码中使用没有意义,因为它实际上并不是异步执行任何操作.如果要将同步代码包装在后台线程中,请使用Task.Run.

关于Parallel.ForEach,您可以通过将其包装在异步中来异步处理它Task.Run:await Task.Run(() => Parallel.ForEach(...));

请注意,并行/后台线程无法直接访问UI元素.如果要从后台/线程池线程更新UI,可以使用IProgress<T>/ Progress<T>.

更新:

序列代码如下所示:

private async void button1_Click(object sender, EventArgs e)
{
  IProgress<string> progress = new Progress<string>(update =>
  {
    listBox1.Items.Add(s);
    btIniciar1.Enabled = false;
  });
  var ts = await Task.Run(() =>
  {
    Stopwatch stopWatch = new Stopwatch();
    foreach (string d in Directory.GetDirectories(@"C:\Visual Studio Projectes\Hash\AsyncAwait\Carpetes"))
    {
      foreach (string s in Directory.GetFiles(d))
      {
        stopWatch.Start();
        progress.Report(s);
      }
    }
    stopWatch.Stop();
    return stopWatch.Elapsed;
  });
  btIniciar1.Enabled = true;
  textBox1.Text = ts.ToString("mm\\:ss\\.ff") + (" minuts");
}
Run Code Online (Sandbox Code Playgroud)

并行代码如下所示:

private async void button1_Click(object sender, EventArgs e)
{
  IProgress<string> progress = new Progress<string>(update =>
  {
    listBox1.Items.Add(s);
    btIniciar1.Enabled = false;
  });
  var ts = await Task.Run(() => Parallel.ForEach( ...
  ));
  btIniciar1.Enabled = true;
  textBox1.Text = ts.ToString("mm\\:ss\\.ff") + (" minuts");
}
Run Code Online (Sandbox Code Playgroud)