Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 并行forEach搜索文件_C#_Winforms_Async Await_Parallel.foreach - Fatal编程技术网

C# 并行forEach搜索文件

C# 并行forEach搜索文件,c#,winforms,async-await,parallel.foreach,C#,Winforms,Async Await,Parallel.foreach,我有一个包含2个列表框的程序,该程序基于搜索文件,然后与秒表比较使用AsyncWait和TPL的区别。。。第一个列表框使用asyncwait(我不知道这是否是更好的方法,但它可以工作,请参阅下面的代码) 然后在我的第二个列表框中,我被卡住了,我不知道如何实现并行?在本例中,我找不到使用TPL的方法来实现与我的第一个列表框相同的功能,您能帮助我吗?在示例代码中使用async没有任何意义,因为它实际上没有异步执行任何操作。如果要将同步代码包装到后台线程中,请使用Task.Run 关于Parallel

我有一个包含2个列表框的程序,该程序基于搜索文件,然后与秒表比较使用AsyncWait和TPL的区别。。。第一个列表框使用
asyncwait
(我不知道这是否是更好的方法,但它可以工作,请参阅下面的代码)


然后在我的第二个列表框中,我被卡住了,我不知道如何实现
并行?在本例中,我找不到使用TPL的方法来实现与我的第一个列表框相同的功能,您能帮助我吗?

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

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

请注意,并行/后台线程不能直接访问UI元素。如果要从后台/线程池线程更新UI,可以使用
IProgress
/
Progress

更新:

串行代码如下所示:

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");
}
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");
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
i进度=新进度(更新=>
{
列表框1.项目。添加;
btIniciar1.Enabled=false;
});
var ts=等待任务。运行(()=>
{
秒表秒表=新秒表();
foreach(Directory.GetDirectories(@“C:\Visual Studio Projectes\Hash\AsyncWait\地毯”)中的字符串d)
{
foreach(Directory.GetFiles(d)中的字符串s))
{
秒表。开始();
进度报告;
}
}
秒表;
返回秒表。已过;
});
btIniciar1.Enabled=true;
textBox1.Text=ts.ToString(“mm\\:ss\\.ff”)+(“minuts”);
}
并行代码如下所示:

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");
}
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");
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
i进度=新进度(更新=>
{
列表框1.项目。添加;
btIniciar1.Enabled=false;
});
var ts=wait Task.Run(()=>Parallel.ForEach(。。。
));
btIniciar1.Enabled=true;
textBox1.Text=ts.ToString(“mm\\:ss\\.ff”)+(“minuts”);
}

最后,我通过以下方式解决了此问题:

 DirectoryInfo nodeDir = new DirectoryInfo(@"c:\files");
 Parallel.ForEach(nodeDir.GetDirectories(), async dir =>
 {
    foreach (string s in Directory.GetFiles(dir.FullName))
    {
       Invoke(new MethodInvoker(delegate { lbxParallel.Items.Add(s); }));
       contador++;
      await Task.Delay(1);
    }
 }

您使用的是winforms还是WPF?此外,还不清楚您想做什么,如果您只是想将文件列表添加到
listBox1
,那么您的并行解决方案会更慢,因为一次只能有一个线程添加项目,每个人都必须等待轮到您。如果您正在做其他事情,ForEach可能会更好,但您需要向我们展示ForEach的真正功能。Parallel.ForEach对此不好,因为只有UI线程可以更新UI,因此您必须更改回该线程,以便将文件实际添加到列表中。如果您确实必须尝试这种实验,最好从函数返回字符串数组(例如文件名)。