C# 中的线程。使用计时器、线程和调用 shell 同时输出所有内容

Posted

技术标签:

【中文标题】C# 中的线程。使用计时器、线程和调用 shell 同时输出所有内容【英文标题】:Threading in C# . Using timer, threads and calling shell with output everything at the same time 【发布时间】:2018-02-21 09:42:28 【问题描述】:

阅读大量有关计时器、线程和调用异步进程(cmd 文件)的文档时,我陷入两难境地,不知道哪种方法和哪种组合最适合我的方案。

我的场景:

    .NET Framework 4.6 的控制台应用程序 我有一个字典,它有一个(作为键)一个 int 表示特定秒的值。 进程从第二个零 (0) 开始 当从开始(步骤 3)经过的秒数与字典的键(在步骤 2 中)相同时,我必须调用一个(或多个)进程(每次都不同,进程启动)。这必须在同一秒内,所以所有调用都必须在不同的线程中(我假设) 此过程需要一秒钟以上才能完成,我有一个异步调用来处理事件以获取响应。

到目前为止我得到了什么:

我每秒运行一个 System.Thread.Timer,其中包含一个示例处理程序,如果该秒有任何值作为键,则该处理程序调用一个进程。 但我不知道必须使用哪个计时器(表单、计时器、线程)才能以更好的性能/方式抱怨这一点。我读过这个,但我认为理解它有点复杂。这也许是我的第一个问题,一个很好的实现。

我也用 Ohad Schneider 的回答来调用这个过程: Is there any async equivalent of Process.Start?

但是,我必须将调用异步/异步的哪个组合与所选类型的计时器一起使用?

我在这里有点迷路,对不起我的英语,任何评论、回答或建议或对这篇文章的版本将不胜感激。感谢您的耐心等待

【问题讨论】:

只是一个快速的选择——“困境”是在两个相等的选项之间进行选择(可以是好选项也可以是坏选项),您无法在它们之间进行选择。它不是“问题”的同义词。 【参考方案1】:

您可以按秒对字典进行排序。然后您就知道每次通话前要等待多少秒。例如,如果您有 5、9、10 和 22 的条目,则在开始第一个进程之前等待 5 秒。之后,您等待 4 秒再拨打下一个电话,以此类推。

这会导致一些非常简单的代码不会进行不必要的轮询:

// this starts at second 00
foreach (var second in dict.OrderBy(d => d.Key))

    var secondsToWait = second.Key - DateTime.Now.Seconds;
    if (secondsToWait > 0)
    
        await Task.Delay(secondsToWait * 1000);
    
    // start your process here

【讨论】:

简单,有效,永远不要那样看。非常感谢【参考方案2】:

我会使用 System.Diagnostics.Stopwatch 作为您的计时器。您可以启动它,拉动经过的秒数,然后检查它当前是否正在运行。

类似:

var s = new System.Diagnostics.Stopwatch();
s.Start();

while(true)

    await Task.Delay(500);
    var secondsElapsed = s.ElapsedMilliseconds / 1000;
    await Task.Run(() => Process.Start(processes[secondsElapsed]));
 

 s.Stop();

【讨论】:

但是如果经过的时间是 4 秒呢,所以我跳了 3 次调用该过程。我理解错了吗? 您说您正在使用秒作为键调用不同的进程。你是说你需要每秒调用一个不同的进程吗? 我想我现在明白你的想法了

以上是关于C# 中的线程。使用计时器、线程和调用 shell 同时输出所有内容的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的线程安全异步代码

c# 定时器调用控件的事件处理事情出现卡死主界面如何解决

有效地将图像文件保存到磁盘 c#

C#多线程之线程池篇3

一个使用两个线程的简单 C# 游戏循环,这样好吗? [关闭]

如何使用 System.Threading.Timer c# 在同一线程上运行代码