簡體   English   中英

C#console批處理應用程序中的最佳計時器方法

[英]Best Timer approach in C# console batch application

哪個是C#控制台批處理應用程序的最佳計時器方法,必須按如下方式處理:

  1. 連接到數據源
  2. 處理批處理直到超時發生或處理完成。 “用數據源做點什么”
  3. 優雅地停止控制台應用程序

相關問題: 如何向C#控制台應用程序添加計時器

很抱歉這是一個完整的控制台應用程序......但這里有一個完整的控制台應用程序,可以幫助您入門。 再一次,我為這么多代碼道歉,但其他人似乎都在給“哦,你所要做的就是做到這一點”答案:)

using System;
using System.Collections.Generic;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static List<RunningProcess> runningProcesses = new List<RunningProcess>();

        static void Main(string[] args)
        {
            Console.WriteLine("Starting...");

            for (int i = 0; i < 100; i++)
            {
                DoSomethingOrTimeOut(30);
            }

            bool isSomethingRunning = false;

            do
            {
                foreach (RunningProcess proc in runningProcesses)
                {
                    // If this process is running...
                    if (proc.ProcessThread.ThreadState == ThreadState.Running)
                    {
                        isSomethingRunning = true;

                        // see if it needs to timeout...
                        if (DateTime.Now.Subtract(proc.StartTime).TotalSeconds > proc.TimeOutInSeconds)
                        {
                            proc.ProcessThread.Abort();
                        }
                    }
                }
            }
            while (isSomethingRunning);

            Console.WriteLine("Done!");    

            Console.ReadLine();
        }

        static void DoSomethingOrTimeOut(int timeout)
        {
            runningProcesses.Add(new RunningProcess
            {
                StartTime = DateTime.Now,
                TimeOutInSeconds = timeout,
                ProcessThread = new Thread(new ThreadStart(delegate
                  {
                      // do task here...
                  })),
            });

            runningProcesses[runningProcesses.Count - 1].ProcessThread.Start();
        }
    }

    class RunningProcess
    {
        public int TimeOutInSeconds { get; set; }

        public DateTime StartTime { get; set; }

        public Thread ProcessThread { get; set; }
    }
}

這取決於您希望停止時間的准確程度。 如果批處理中的任務相當快,而且您不需要非常准確,那么我會嘗試使其成為單線程:

DateTime runUntil = DataTime.Now.Add(timeout);
forech(Task task in tasks)
{
   if(DateTime.Now >= runUntil)
   {
        throw new MyException("Timeout");
   }
   Process(task);
}

否則你需要多線程,這總是比較困難,因為你需要弄清楚如何在中間終止任務而不會產生副作用。 您可以使用System.Timers中的Timer: http//msdn.microsoft.com/en-us/library/system.timers.timer (VS.71) .aspx或Thread.Sleep。 發生超時事件時,您可以終止執行實際處理的線程,清理並結束該過程。

當你說“直到發生超時”時你的意思是“繼續處理一小時然后停止”? 如果是這樣,我可能只是非常明確地說 - 在你想要完成時從頭開始工作,然后在你的處理循環中,檢查你是否已經達到那個時間。 它非常簡單,易於測試等。在可測試性方面,您可能需要一個可以讓您以編程方式設置時間的假時鍾。

編輯:這是一些試圖澄清的偽代碼:

List<DataSource> dataSources = ConnectToDataSources();
TimeSpan timeout = GetTimeoutFromConfiguration(); // Or have it passed in!
DateTime endTime = DateTime.UtcNow + timeout;

bool finished = false;
while (DateTime.UtcNow < endTime && !finished)
{
    // This method should do a small amount of work and then return
    // whether or not it's finished everything
    finished = ProcessDataSources(dataSources);
}

// Done - return up the stack and the console app will close.

這只是使用內置時鍾而不是可以模擬的時鍾接口等 - 但它可能使得一般更容易理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM