【问题标题】:C# Thread async processingC# 线程异步处理
【发布时间】:2017-10-24 03:02:59
【问题描述】:

我有一个我选择线程化的应用程序。这样做的目的是一次运行多个线程以加快应用程序的速度。

目前我循环应用程序设置,为每个设置创建一个线程,然后启动每个设置,然后加入,这样我就可以知道它们何时都完成了。

不幸的是,这样做时,每个线程都是同步运行的,这违背了目的。

我可以更改它以删除连接,但是我无法确定所有线程何时完成(我需要这样做,因为它们都完成了,我只有一个进程要运行)。

我开始认为线程不适合我,但我应该更多地研究 threading.tasks 或 parallel.foreach,但我不确定其中任何一个的复杂性。我之前没有使用过任何一种机制(也只涉足线程)

以下是当前生成我的线程的代码 sn-p

foreach (SettingsProperty value in Properties.Settings.Default.Properties)
{
    //parse out the line in the settings
    if (value.Name.ToString() != <<criteria>>)
    {
        //this is one that we want to do something with
        sett = value.DefaultValue.ToString().Split(stringSeparators, StringSplitOptions.None);

        //set the directory
        Directory.CreateDirectory(<<directory>>);

        //fire the thread to retrieve the image form the url
        ThreadWithState tws = new ThreadWithState(<<parameters>>);
        Thread t = new Thread(new ThreadStart(tws.ThreadProc));
        t.Start();
        t.Join();

    }
}
UploadFiles();

目前这会一一执行线程,然后执行最后一个进程。如果我删除 t.join 调用,这会异步运行线程,但也会在所有线程完成之前执行上传。

如何更改此代码以等待所有线程完成,或者 实施 Parallel.ForEach (我认为这可能有效,但不了解)或 实现一些 threading.tasks 函数,以便我可以使用 Task.WhenAll 方法(我认为它也可以工作但不了解)

【问题讨论】:

  • 你为什么打电话给t.Join()?
  • 你的问题太宽泛了。有很多有效的方法可以同时运行。您的代码没有尝试任何这些方式。通过在刚刚启动的线程上立即调用Join(),您不会在当前线程完成之前启动另一个线程。如果您不想在启动另一个线程之前等待,那么不要等待。
  • 你说你知道什么是正确的工具——构建一个异步工作流——但你不知道如何去做。所以学习如何去做。这不是一个教程网站;有很多关于并行和异步工作流的教程。去拿一个!对于像这样的 IO 绑定任务,我将从学习异步工作流开始。无需涉及多个线程。

标签: c# multithreading asynchronous parallel-processing task


【解决方案1】:

Thread.Join() 指示正在执行的线程阻塞(等待)直到另一个线程完成其任务。

所以这个

t.Start();
t.Join();

字面意思是开始任务,在完成之前什么都不做。

如果你想使用Parallel.ForEach,你可以从创建你想要操作的列表开始。例如,

var properties = Properties.Settings.Default.Properties
    .Where(property => Name != "whatever");

现在properties 是IEnumerable&lt;SettingsProperty&gt; - 一个可以枚举或循环的集合。

现在你可以这样做了:

Parallel.ForEach(properties, (property) =>
    {
        // do something with the property.
    });

这与

基本相同
foreach(var property in properties)
{
    // do something with the property.
}

除了循环的迭代可能在并发线程上运行。 “可能”,因为任务调度程序根据工作负载和可用线程使用线程。

【讨论】:

    猜你喜欢
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2014-07-04
    • 2021-02-26
    相关资源
    最近更新 更多