[英]Best Timer approach in C# console batch application
哪個是C#控制台批處理應用程序的最佳計時器方法,必須按如下方式處理:
相關問題: 如何向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.