【问题标题】:Using System.Timers with a console application and output type 'Windows Application'将 System.Timers 与控制台应用程序和输出类型“Windows 应用程序”一起使用
【发布时间】:2017-07-09 01:42:14
【问题描述】:

对于使用计时器的典型控制台应用程序,我们可以使用“Console.ReadLine()”来防止应用程序关闭。当控制台应用程序的输出类型为“Windows 应用程序”时,是否有等效的解决方案?

旁注:在这种情况下,Windows 服务不是解决方案,因为我正在启动进程。

class Program
{        
    private static Timer _Timer;       

    static void Main(string[] args)
    {   
        SetupTimer();                        
    }

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {           
        Process.Start(@"C:\WINDOWS\system32\notepad.exe");
    }

    private static void SetupTimer()
    {
        _Timer = new Timer();
        _Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        _Timer.Interval = 3000;
        _Timer.Enabled = true;
    }
}

【问题讨论】:

  • 一个windows应用程序有一个窗口,只要窗口没有关闭,定时器就会运行。关闭窗口是关闭窗口的用户命令,就像在控制台中输入键是关闭控制台的命令一样。不知道你在这里问什么。
  • @CodingYoshi 见这里。我的应用程序没有要关闭的窗口。 stackoverflow.com/questions/2686289/…
  • 目前还不是很清楚为什么要使用定时器。你没有 UI 来保持快乐,所以 Thread.Sleep() 也可以做到。
  • @HansPassant 为什么我要使用计时器与我的问题无关,但这是因为我想监视另一个进程,一旦它终止,启动另一个应用程序。 Thread.Sleep() 将完成这项工作。谢谢
  • 存储Process.Start()返回的Process实例,然后使用它的WaitForExit()方法?....

标签: c# console-application windows-applications


【解决方案1】:

实现你想要的:

using System;
using System.Diagnostics;
using System.Timers;

public class Program
{
    private static Timer _Timer;
    private static bool Launched = false;
    static void Main(string[] args)
    {
        SetupTimer();
        WaitUntilItIsLaunched:
        if (!Launched)
        {
            System.Threading.Thread.Sleep(100);
            goto WaitUntilItIsLaunched;
        }
    }

    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        Process.Start(@"C:\WINDOWS\system32\notepad.exe");
        Launched = true;
    }

    private static void SetupTimer()
    {
        _Timer = new Timer();
        _Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        _Timer.Interval = 3000;
        _Timer.Enabled = true;
    }
}

【讨论】:

  • 好的,所以我们只是不断地让线程休眠,直到满足我的条件。不是很优雅,但谢谢。
  • 您可以使用任务和线程控制,但这对您来说更难理解。但这并不是一个糟糕的解决方案。
【解决方案2】:

或者更简洁的代码:

using System;
using System.Diagnostics;
using System.Threading;
public class Program
{
    static void Main(string[] args)
    {
        DateTime LaunchAt = DateTime.Now.AddSeconds(3);
        WaitLaunch:
        Thread.Sleep(100);
        if (DateTime.Now >= LaunchAt)
            Process.Start(@"C:\WINDOWS\system32\notepad.exe");
        else
            goto WaitLaunch;
    }
}

【讨论】:

  • 线程.Sleep(100);是一段很重要的代码,因为没有它,处理器会继续每秒循环数百万次,导致处理器 100% 的容量被使用。
【解决方案3】:

如果您想在不同时间启动多个程序并等待它们全部启动:

using System;
using System.Diagnostics;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
public class Program
{
    static Dictionary<string,DateTime> ExecutablesToLaunch = new Dictionary<string,DateTime>();
    static List<string> ExecutablesLaunched = new List<string>();
    static void Main(string[] args)
    {
        ExecutablesToLaunch.Add(@"C:\WINDOWS\system32\notepad.exe", DateTime.Now.AddSeconds(3));
        ExecutablesToLaunch.Add(@"C:\WINDOWS\system32\control.exe", DateTime.Now.AddSeconds(5));
        ExecutablesToLaunch.Add(@"C:\WINDOWS\system32\calc.exe", DateTime.Now.AddSeconds(10));

        WaitAllToLaunch:
        if (ExecutablesToLaunch.Count == ExecutablesLaunched.Count)
            return;
        Thread.Sleep(100);
        foreach (var Executable in ExecutablesToLaunch)
        {
            if (ExecutablesLaunched.Contains(Executable.Key))
                continue;
            if (DateTime.Now >= Executable.Value)
            {
                Process.Start(Executable.Key);
                ExecutablesLaunched.Add(Executable.Key);
            }
            else
                goto WaitAllToLaunch;
        }
    }

}

【讨论】:

    【解决方案4】:

    代码行数更少:

    using System;
    using System.Diagnostics;
    using System.Threading.Tasks;
    using System.Timers;
    public class Program
    {
        static void Main(string[] args)
        {
            int MsToWait = 3000;
            int MsElapsed = 0;
            WaitLaunch:
            System.Threading.Thread.Sleep(100);
            MsElapsed += 100;
            if (MsElapsed >= MsToWait)
            {
                Process.Start(@"C:\WINDOWS\system32\notepad.exe");
                return;
            }
            else
                goto WaitLaunch;
        }
    }
    

    【讨论】:

    • 当你可以使用时不要使用goto,你可以使用常规循环并拥有更可读的代码。
    • 也不要对同一个问题发布多个答案。
    • 我会发布尽可能多的答案,只要它们是正确的并且它们之间存在显着差异。如果您认为 goto 无法阅读,那么您必须给出完整的答案,如果您不这样做,您就不会在这里帮助任何人。在这种情况下,goto 比计时器更具可读性。
    猜你喜欢
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 2010-11-04
    • 1970-01-01
    • 2011-01-07
    相关资源
    最近更新 更多