我想开发一个 Windows 控制台应用程序,它在给定时间后定期执行一个操作。我在某处读到计时器类仅适用于 Windows 窗体应用程序,那么完成我想要的东西的最佳方法是什么?
最佳答案
Original message: I wrote this sample console application (using C# 4.0 [as indicated by the default parameters]). It's extremely versatile and utilizes the Action delegate to allow passing snippets that you want executed using the Timer class (in System.Threading). The overloaded Do method of the At static class does all the legwork of computing the interval of delay. You can optionally have the snipped repeated by specifying an interval (in milliseconds). You can of course modify the method to accept TimeSpan for the repeat interval.
三年前提供的控制台应用程序示例已证明非常受寻求此类性质的人们的欢迎。提出的许多问题都与作业计划管理有关。我试着编写一个可以相当简单地实现的新类。它仅作为使用示例提供。对于那些认为我的风格低劣或充斥着不必要代码的人,我觉得这很好。您可以根据自己的编程风格、实现实践等对其进行调整。
类的以下更改使其更有用:
什么没有改变?
向下滚动找到该类的新实现。享受吧!
** 旧控制台类如下:**
using System;
using System.Threading;
namespace ConsoleApplication1
{
/// <summary>
/// Class that manages the execution of tasks sometime in the future.
/// </summary>
public static class At
{
#region Members
/// <summary>
/// Specifies the method that will be fired to execute the delayed anonymous method.
/// </summary>
private readonly static TimerCallback timer = new TimerCallback(At.ExecuteDelayedAction);
#endregion
#region Methods
/// <summary>
/// Method that executes an anonymous method after a delay period.
/// </summary>
/// <param name="action">The anonymous method that needs to be executed.</param>
/// <param name="delay">The period of delay to wait before executing.</param>
/// <param name="interval">The period (in milliseconds) to delay before executing the anonymous method again (Timeout.Infinite to disable).</param>
public static void Do(Action action, TimeSpan delay, int interval = Timeout.Infinite)
{
// create a new thread timer to execute the method after the delay
new Timer(timer, action, Convert.ToInt32(delay.TotalMilliseconds), interval);
return;
}
/// <summary>
/// Method that executes an anonymous method after a delay period.
/// </summary>
/// <param name="action">The anonymous method that needs to be executed.</param>
/// <param name="delay">The period of delay (in milliseconds) to wait before executing.</param>
/// <param name="interval">The period (in milliseconds) to delay before executing the anonymous method again (Timeout.Infinite to disable).</param>
public static void Do(Action action, int delay, int interval = Timeout.Infinite)
{
Do(action, TimeSpan.FromMilliseconds(delay), interval);
return;
}
/// <summary>
/// Method that executes an anonymous method after a delay period.
/// </summary>
/// <param name="action">The anonymous method that needs to be executed.</param>
/// <param name="dueTime">The due time when this method needs to be executed.</param>
/// <param name="interval">The period (in milliseconds) to delay before executing the anonymous method again (Timeout.Infinite to disable).</param>
public static void Do(Action action, DateTime dueTime, int interval = Timeout.Infinite)
{
if (dueTime < DateTime.Now)
{
throw new ArgumentOutOfRangeException("dueTime", "The specified due time has already elapsed.");
}
Do(action, dueTime - DateTime.Now, interval);
return;
}
/// <summary>
/// Method that executes a delayed action after a specific interval.
/// </summary>
/// <param name="o">The Action delegate that is to be executed.</param>
/// <remarks>This method is invoked on its own thread.</remarks>
private static void ExecuteDelayedAction(object o)
{
// invoke the anonymous method
(o as Action).Invoke();
return;
}
#endregion
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Time: {0} - started", DateTime.Now);
// demonstrate that order is irrelevant
At.Do(() => Console.WriteLine("Time: {0} - Hello World! (after 5s)", DateTime.Now), DateTime.Now.AddSeconds(5));
At.Do(() => Console.WriteLine("Time: {0} - Hello World! (after 3s)", DateTime.Now), DateTime.Now.AddSeconds(3));
At.Do(() => Console.WriteLine("Time: {0} - Hello World! (after 1s)", DateTime.Now), DateTime.Now.AddSeconds(1));
At.Do
(
() =>
{
// demonstrate flexibility of anonymous methods
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Time: {0} - Hello World! - i == {1} (after 4s)", DateTime.Now, i);
}
},
TimeSpan.FromSeconds(4)
);
// block main thread to show execution of background threads
Thread.Sleep(100000);
return;
}
}
}
** 新类提供如下:**
using System;
using System.Linq;
using System.Threading;
using System.Collections.Generic;
namespace Utility
{
/// <summary>
/// Class that is designed to execution Action-based anonymous delegates after a specified
/// interval. This class also supports repetitive tasks on an interval.
/// </summary>
public static class At
{
#region Embedded Classes
/// <summary>
/// Embedded class definition for common At job periods.
/// </summary>
public static class Periods
{
#region Members
/// <summary>
/// Specifies an object that indicates to not restart.
/// </summary>
public static readonly TimeSpan DoNotStart = TimeSpan.FromMilliseconds(-1.0);
/// <summary>
/// Specifies an object that indicates to start immediately.
/// </summary>
public static readonly TimeSpan Immediately = TimeSpan.FromMilliseconds(0.0);
/// <summary>
/// Specifies an interval of one second.
/// </summary>
public static readonly TimeSpan SecondsOne = TimeSpan.FromSeconds(1.0);
/// <summary>
/// Specifies an interval of five seconds.
/// </summary>
public static readonly TimeSpan SecondsFive = TimeSpan.FromSeconds(5.0);
/// <summary>
/// Specifies an interval of fifteen seconds.
/// </summary>
public static readonly TimeSpan SecondsFifteen = TimeSpan.FromSeconds(15.0);
/// <summary>
/// Specifies an interval of thirty seconds.
/// </summary>
public static readonly TimeSpan SecondsThirty = TimeSpan.FromSeconds(30.0);
/// <summary>
/// Specifies an interval of 100ms.
/// </summary>
public static readonly TimeSpan MicroDelay = TimeSpan.FromMilliseconds(100);
#endregion
}
#endregion
#region Members
/// <summary>
/// Specifies an object that can be used for synchronization.
/// </summary>
private readonly static object syncRoot;
/// <summary>
/// Specifies a collection of Timer object that were created for interval-based execution.
/// </summary>
/// <remarks>
/// We must keep these in a collection to prevent the GC from disposing of the timers.
/// </remarks>
private readonly static Dictionary<object, Timer> ActiveTimers;
/// <summary>
/// Specifies a collection of timestamps of when timers are created.
/// </summary>
private readonly static Dictionary<object, DateTime> TimerCreation;
/// <summary>
/// Specifies an object that will produce pseudo-random numbers.
/// </summary>
private readonly static Random RNG;
#endregion
#region Static Constructor
static At()
{
syncRoot = new object();
ActiveTimers = new Dictionary<object, Timer>();
TimerCreation = new Dictionary<object, DateTime>();
RNG = new Random();
// "deconstructor"
AppDomain.CurrentDomain.DomainUnload += new EventHandler(CurrentDomain_DomainUnload);
return;
}
/// <summary>
/// Method used to cleanup resources used by this object.
/// </summary>
static void CurrentDomain_DomainUnload(object sender, EventArgs e)
{
// dispose of all the timers directly
At.ActiveTimers.Values.ToList().ForEach(a => a.Dispose());
return;
}
#endregion
#region Methods
#region At Job Staging
/// <summary>
/// Method that executes an anonymous method after a delay period.
/// </summary>
/// <param name="action">The anonymous method that needs to be executed.</param>
/// <param name="delay">The period of delay to wait before executing.</param>
/// <param name="interval">The period (in milliseconds) to delay before executing the anonymous method again (Timeout.Infinite to disable).</param>
public static Timer Do(Action action, TimeSpan delay, TimeSpan? onInterval = null, object key = null)
{
Timer timer;
if (key == null)
{
// auto-generate a key
key = string.Concat("Auto(", At.RNG.NextNonNegativeLong(), ")");
}
lock (At.ActiveTimers)
{
// action - contains the method that we wish to invoke
At.ActiveTimers.Add(key, timer = new Timer(ActionInvoker, action, delay, onInterval ?? At.Periods.DoNotStart));
At.TimerCreation.Add(key, DateTime.Now);
}
//Log.Message
//(
// LogMessageType.Debug,
// "[DEBUG] {0}: registered At job (key = {1}, initial delay = {2}, interval = {3})",
// action,
// key,
// delay,
// (onInterval == null) ? "never" : onInterval.Value.ToString()
//);
return timer;
}
/// <summary>
/// Method that executes an anonymous method after a delay period.
/// </summary>
/// <param name="action">The anonymous method that needs to be executed.</param>
/// <param name="delay">The period of delay (in milliseconds) to wait before executing.</param>
/// <param name="interval">The period (in milliseconds) to delay before executing the anonymous method again (Timeout.Infinite to disable).</param>
public static Timer Do(Action action, int delay, int interval = Timeout.Infinite, object key = null)
{
return Do(action, TimeSpan.FromMilliseconds(delay), TimeSpan.FromMilliseconds(interval), key);
}
/// <summary>
/// Method that executes an anonymous method after a delay period.
/// </summary>
/// <param name="action">The anonymous method that needs to be executed.</param>
/// <param name="dueTime">The due time when this method needs to be executed.</param>
/// <param name="interval">The period (in milliseconds) to delay before executing the anonymous method again (Timeout.Infinite to disable).</param>
public static Timer Do(Action action, DateTime dueTime, int interval = Timeout.Infinite, object key = null)
{
if (dueTime < DateTime.Now)
{
throw new ArgumentOutOfRangeException("dueTime", "The specified due time has already elapsed.");
}
return Do(action, dueTime - DateTime.Now, TimeSpan.FromMilliseconds(interval), key);
}
#endregion
#region At Job Retrieval
/// <summary>
/// Method that attempts to retrieve a job (Timer object) for a given key.
/// </summary>
/// <param name="key">The key that we are getting a job for.</param>
public static Timer GetJobFor(object key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
lock (At.ActiveTimers)
{
if (At.ActiveTimers.ContainsKey(key) == false)
{
/*
Log.Message
(
LogMessageType.Error,
"[ERROR] At({0}): unable to find a job with specified key",
key
);
*/
return null;
}
return At.ActiveTimers[key];
}
}
/// <summary>
/// Method that ends a job and removes all resources associated with it.
/// </summary>
/// <param name="key">The key that we are getting a job for.</param>
public static void EndJob(object key)
{
Timer timer;
if ((timer = GetJobFor(key)) == null)
{
// no timer - cannot suspend
return;
}
// dispose of the timer object
timer.Dispose();
lock (At.ActiveTimers)
{
// remove the existence from the dictionary
At.ActiveTimers.Remove(key);
/*
Log.Message
(
LogMessageType.Info,
"[INFO] At({0}): job has been disposed (created {1}, duration {2})",
key,
TimerCreation[key].ToISODateTime(),
(DateTime.Now - TimerCreation[key]).ToText()
);
*/
At.TimerCreation.Remove(key);
}
return;
}
/// <summary>
/// Method that attempts to suspend an active job (using the provided key).
/// </summary>
/// <param name="key">The key that we are getting a job for.</param>
public static void SuspendJob(object key)
{
Timer timer;
if ((timer = GetJobFor(key)) == null)
{
// no timer - cannot suspend
return;
}
// set the timer to not restart
timer.Change(TimeSpan.FromMilliseconds(-1), TimeSpan.FromMilliseconds(-1));
/*
Log.Message
(
LogMessageType.Info,
"[INFO] At({0}): job has been suspended",
key
);
*/
return;
}
/// <summary>
/// Method that attempts to resume an active job (using the provided key).
/// </summary>
/// <param name="key">The key that we are getting a job for.</param>
/// <param name="delay">The amount of delay before restarting the job (specify <b>0</b> to restart immediately).</param>
/// <param name="interval">The delay between intervals (specify <b>-1ms</b> to prevent intervals).</param>
public static void ResumeJob(object key, TimeSpan delay, TimeSpan interval)
{
Timer timer;
if ((timer = GetJobFor(key)) == null)
{
// no timer - cannot suspend
return;
}
// set the timer to not restart
timer.Change(delay, interval);
/*
Log.Message
(
LogMessageType.Info,
"[INFO] At({0}): job has been resumed (delay = {1}, interval = {2})",
key,
delay,
interval
);
*/
return;
}
#endregion
/// <summary>
/// Method that invokes an action delegate on a timer.
/// </summary>
/// <param name="o">A reference to the action that is to be taken.</param>
private static void ActionInvoker(object o)
{
// invoke the delegate
(o as Action).Invoke();
return;
}
#endregion
}
}
关于C# 在 X 秒后执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3756038/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption