异步控制台应用或服务?

时间:2014-03-17 01:49:33

标签: c# multithreading asynchronous service console

我正在尝试创建一个C#.net 4.5控制台应用程序,它将继续运行循环,除非从用户传递命令。我不希望每次循环完成时都检查用户的输入,因为我希望它在没有用户输入的情况下运行至少几小时,甚至可能更长,但是他们应该能够随时在控制台中输入命令评估循环应该如何表现。

为了在循环运行的同时允许用户输入我相信我需要使用诸如之类的线程,但是我对编程很新,我不确定线程​​是否甚至是正确的方法。我最近也学到了服务,因为用户输入主要是停止和启动,这可能是更好的方法。

我应该如何修改下面的代码来实现允许用户在运行连续循环时输入的异步功能?这应该是一项服务,因为大多数用户输入是开始和停止?

我已经包含了我到目前为止编写的代码:

class Program
{
    static void Main(string[] args)
    {
        OptionMenu();
        Console.ReadLine();
    }        

    static void OptionMenu()
    {
        string command = "";
        Console.WriteLine("Please enter a command: \n");
        while (command != "exit")
        {
            command = Console.ReadLine().ToLower();
            switch (command)
            {
                case "exit":
                    command = "exit";
                    break;
                case "pause":
                    command = "Pause";
                    break;
                case "start":                        
                    while (command != "Pause")
                    {
                        PrimaryWork();
                    }
                    break;
                default:
                    Console.WriteLine("I'm sorry Dave, I'm afraid I can't do that");
                    break;
            }
        }
    }

    static void PrimaryWork()
    {
        Console.WriteLine("Results of PrimaryWork should be written to a repository");
        Thread.Sleep(5000);
    }
}

2 个答案:

答案 0 :(得分:3)

这是一个可能对您有帮助的模式:

void Main()
{
    var tokenSource = new CancellationTokenSource();
    var t=new Thread(_ => DoWork(tokenSource.Token));
    for(;;) //loop forever
    {
        var input = Console.ReadLine();
        if(input == "exit") 
        {
            tokenSource.Cancel();
            break;
        }
    }
}

void DoWork(CancellationToken token)
{
    for(;;)
    {
        //do some work
        if(token.IsCancellationRequested)
        {
            break;
        }
    }
}

答案 1 :(得分:0)

在这种情况下,使用async / await不太可能使您的代码更容易。

考虑创建处理“主要工作”的单独线程,并将主线程发布命令发送到ConcurrentQueue,这将由其他线程检查。

起点Thread.Start

var commands = new ConcurrentQueue<string>();
var myThread = new Thread(_ =>
  {
      while(true)
      {
         // Do work
         ...
        // check commands
        string command;
        if (commands.TryDequeue(out command))
        { 
             //handle command
        }
      }
  });
myThread.Start();

commands.Enqueue(Console.ReadLine());