我总是注意到人们对在UNIX中创建计时器的不同方式有不同的反应.
我知道在UNIX中每隔X秒执行一次事件的几种不同方法:
有人可以提供一些示例代码,使用"最佳"或最有效的方式来执行计时器,并说明为什么它是最好的?我想使用最有效的机制,但我不确定它是哪一个!
出于我们的目的,只是假装你正在打印"Hello World!" 每10秒一次.
注意:我没有TR1/Boost/etc.在这个系统上,所以请保持它直接进行C/C++和UNIX系统调用.对不起,第一次没有提到:)
我有一个使用Jabber-net(XMPP库)的应用程序的消息传递方面.
我想做什么,如果由于某种原因与服务器的连接结束,就是每隔一分钟左右继续尝试连接.
如果我在下一次尝试之前启动一个Timer等待一段时间,那个定时器是否异步运行并且生成的Tick事件加入主线程,还是我需要启动自己的线程并从那里启动定时器?
我有一个计时器,不需要同时处理其已用的事件处理程序.但处理一个Elapsed事件可能会干扰其他事件.我实施了以下解决方案,但感觉不对劲; 似乎要么我应该使用不同的计时器,要么在线程空间内使用另一个对象.计时器似乎最合适,因为我确实需要定期检查状态,但有时检查将花费比我的间隔更长的时间.这是解决这个问题的最佳方法吗?
// member variable
private static readonly object timerLock = new object();
private bool found = false;
// elsewhere
timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Elapsed = Timer_OnElapsed;
timer.Start();
public void Timer_OnElapsed(object sender, ElapsedEventArgs e)
{
lock(timerLock)
{
if (!found)
{
found = LookForItWhichMightTakeALongTime();
}
}
}
Run Code Online (Sandbox Code Playgroud) 我创建了一个Windows服务,它应该每隔60秒检查数据库中的某个表以获取新行.对于添加的每个新行,我需要在服务器上进行一些繁重的处理,有时可能需要超过60秒.
我在我的服务中创建了一个Timer对象,每隔60秒就会调用一次,并调用所需的方法.
由于我不想在处理找到的新行时勾选此计时器lock { },因此我将该方法包装在一个块中,因此其他线程无法访问此方法.
它看起来像这样:
Timer serviceTimer = new Timer();
serviceTimer.Interval = 60;
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Start();
void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (this)
{
// do some heavy processing...
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想知道 -
如果我的计时器滴答,并在数据库上发现了很多新行,现在处理将花费超过60秒,下一个滴答将不会进行任何处理,直到前一个完成.这就是我想要的效果.
但现在,serviceTimer_Elapsed方法会在第一次处理完成后立即关闭,还是会等待计时器再次打勾.
我想要发生的是 - 如果处理需要超过60秒,那么计时器会注意到线程被锁定,再等待60秒再次检查,这样我就永远不会陷入有线程队列的情况等待前一个完成.
我怎样才能完成这个结果?
这样做的最佳做法是什么?
谢谢!
我想在Android服务中创建一个每X秒运行一次的线程
我目前正在使用,但postdelayed方法似乎真的滞后我的应用程序.
@Override
public int onStartCommand(Intent intent, int flags, int startId){
super.onStartCommand(intent, flags, startId);
startRepeatingTask();
return startId;
}
private final static int INTERVAL = 20000; //20 milliseconds
Handler m_handler = new Handler();
Runnable m_handlerTask = new Runnable()
{
@Override
public void run() {
// this is bad
m_handler.postDelayed(m_handlerTask, INTERVAL);
}
};
void startRepeatingTask()
{
m_handlerTask.run();
}
void stopRepeatingTask()
{
m_handler.removeCallbacks(m_handlerTask);
stopSelf();
}
Run Code Online (Sandbox Code Playgroud)
我想做一个这样的新线程:
public void threadRun()
{
Thread triggerService = new Thread(new Runnable(){
public void run(){
Looper.prepare();
try{
//do stuff …Run Code Online (Sandbox Code Playgroud) 使用ScheduledExecutorService/ Timer/有Handler什么优缺点 ?据我所知,在Android中而不是Timer它需要使用Handler,但是怎么样ScheduledExecutorService?
据我所知Handler,ScheduledExecutorService只是相对时间,对吗?
我正在尝试通过改变一天中的时间为游戏制作一个简单的脚本,但我想以快速的方式进行.所以这就是我所说的:
function disco ( hour, minute)
setTime ( 1, 0 )
SLEEP
setTime ( 2, 0 )
SLEEP
setTime ( 3, 0 )
end
Run Code Online (Sandbox Code Playgroud)
等等.我该怎么做呢?
很明显:例如,想象一下我的表格中的一个按钮.当用户单击该按钮时,某些void方法应在30秒后运行.
将有一个带有DoAfterDelay两个输入参数的void方法.第一个是要做的方法(使用委托),另一个是时间间隔.所以我会:
public delegate void IVoidDelegate();
static void DoAfterDelay(IVoidDelegate TheMethod, TimeSpan Interval)
{
// *** Some code that will pause the process for "Interval".
TheMethod();
}
Run Code Online (Sandbox Code Playgroud)
所以,我只需要一段代码来暂停特定时间间隔的过程.到目前为止,我使用此代码执行此操作:
System.Threading.Thread.Sleep(Interval);
Run Code Online (Sandbox Code Playgroud)
但是这段代码对我没有好处,因为它会停止整个过程并冻结程序.我不希望程序卡在DoAfterDelay方法中.这就是为什么Thread.Sleep没用.
所以有人可以提出更好的方法吗?当然我已经搜索过了,但我发现的大部分解决方案都是基于使用计时器(比如这里).但是使用计时器是我最后的意见,因为该方法应该运行一次并且使用计时器会使程序混淆读取.所以,如果有的话,我正在寻找更好的解决方案.或者我可能必须使用计时器?
我想我必须玩线程,但不确定.所以我想知道是否有人可以指导我找到解决方案.提前致谢.
我有异步回调,它被传递到Timer(来自System.Threading)构造函数:
private async Task HandleTimerCallback(object state)
{
if (timer == null) return;
if (asynTaskCallback != null)
{
await HandleAsyncTaskTimerCallback(state);
}
else
{
HandleSyncTimerCallback(state);
}
}
Run Code Online (Sandbox Code Playgroud)
和计时器:
timer = new Timer(async o => await HandleTimerCallback(o), state, CommonConstants.InfiniteTimespan,
CommonConstants.InfiniteTimespan);
Run Code Online (Sandbox Code Playgroud)
有没有办法o在lambda中省略那个参数?非同步的原因我可以将我handler作为委托传递
timer = new Timer(HandleTimerCallback, state, CommonConstants.InfiniteTimespan,
CommonConstants.InfiniteTimespan);
Run Code Online (Sandbox Code Playgroud) timer ×10
c# ×5
.net ×2
android ×2
async-await ×1
asynchronous ×1
c ×1
concurrency ×1
javascript ×1
lambda ×1
linux ×1
lua ×1
sleep ×1
unix ×1
wait ×1
winforms ×1