English 中文(简体)
如果前线仍然忙 the,如何让步者跳板
原标题:How to let Timer skip tick if the previous thread is still busy

我创建了一个窗口服务,即每60秒钟在管道中检查某个桌子。 对于增加的每个新行,我需要在服务器上进行一些重处理,有时可能需要60秒。

I created a Timer object in my service, that ticks every 60 seconds and invokes the wanted method.
Since I don t want this timer to tick while processing the new lines found, I wrapped the method in a lock { } block, so this won t be accessible by another thread.

它看着这样的情况:

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...
    }
}

Now, I m wondering -
If my timer ticks, and finds a lot of new rows on the db, and now the processing will take more than 60 seconds, the next tick won t do any processing till the previous one finished. This is the effect I want.

但是,现在,这项服务将是 螺旋-Elapsed方法一旦完成第一次处理,即立即失效,或者将等待时间。

我想要的是——如果处理需要60秒以上的时间,就会把read锁锁起来,再等待60秒钟,以便我永远不会陷入等待上台的人到底的境地。

How can i accomplish this result ?
What is the best practice for doing this ?

感谢!

最佳回答

在加工过程中,你可能会试图拆解时间,例如:

// Just in case someone wants to inherit your class and lock it as well ...
private static object _padlock = new object();
try
{
  serviceTimer.Stop(); 

  lock (_padlock)
    { 
        // do some heavy processing... 
    } 
}
finally
{
  serviceTimer.Start(); 
}

http://www.ohchr.org。 执行部分第1段没有具体说明,重新启用是否只是由时间推算,还是服务多读。 越晚,如果时间被拦截(AutoReset或人工操作)则不必再锁定。

问题回答

You don t need the lock in this case. Set timer.AutoReset=false before starting it. Restart the timer in the handler after you are done with your processing. This will ensure that the timer fires 60 seconds after each task.

在其他答复方面也有类似的改动,使时间者能够保持定时,而且只能在能够打上锁时,而不是停止工作。

在以往活动中担任主管:

if (Monitor.TryEnter(locker)
{
    try
    {
        // Do your work here.
    }
    finally
    {
        Monitor.Exit(locker);
    }
}

进行快速检查,看看看服务是否运行。 如果它正在运行,它就会绕过这次事件,等待下一场火灾。

Timer serviceTimer = new Timer();
serviceTimer.Interval = 60;
serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Start();
bool isRunning = false;
void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    lock (this)
    {
        if(isRunning)
            return;
        isRunning = true;
    }
    try
    {
    // do some heavy processing...
    }
    finally
    {
        isRunning = false;
    }
}

我建议你不要让时间在进行处理时打上。

Set the Timers AutoReset to false. And start it at the end. Here s a full answer you might be interested in Needed: A Windows Service That Executes Jobs from a Job Queue in a DB; Wanted: Example Code

其他选择可能是利用“后方工作”班,或“后方工作”班。

背景工作者很容易就目前仍在进行的处理进行选择检查,同时处理1个项目。 托马普勒将使你能够继续将各种物品(如有必要)排在背景线上。

根据您的描述,我假定你正在一个数据库中查询各个项目。 在这种情况下,我将利用ThreadPool把工作推向背景,而不是放慢/停止检查机制。

www.un.org/Depts/DGACM/index_spanish.htm 对于一个处,我确实建议你研究如何使用ThreadPool办法。 这样,你就可以每60秒与你的时间对新物品进行核对,然后对新物品进行盘问,让你去。 净数字显示,分配给每个项目的资金有多少,而且只是继续把这些项目推到桌面上。

<><>For Example>: 如果你只使用一台时间,你有5个新行,需要65秒的加处理时间。 采用ThreadPool办法,将在65秒中完成,有5个背景工作项目。 采用时间办法,这将需要4+分钟(你将在每行之间等待一分钟),这还可能导致对正在处理的其他工作的反馈。

这方面的一个例子是应如何做到这一点:

Timer serviceTimer = new Timer();
    void startTimer()
    {
        serviceTimer.Interval = 60;
        serviceTimer.Elapsed += new ElapsedEventHandler(serviceTimer_Elapsed);
        serviceTimer.AutoReset = false;
        serviceTimer.Start();
    }
    void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {
            // Get your rows of queued work requests

            // Now Push Each Row to Background Thread Processing
            foreach (Row aRow in RowsOfRequests)
            {
                ThreadPool.QueueUserWorkItem(
                    new WaitCallback(longWorkingCode), 
                    aRow);
            }
        }
        finally
        {
            // Wait Another 60 Seconds and check again
            serviceTimer.Stop();
        }
    }

    void longWorkingCode(object workObject)
    {
        Row workRow = workObject as Row;
        if (workRow == null)
            return;

        // Do your Long work here on workRow
    }

另一种可能性是:

void serviceTimer_Elapsed(object sender, ElapsedEventArgs e)
{   
    if (System.Threading.Monitor.IsLocked(yourLockingObject))
       return;
    else
       lock (yourLockingObject)
       // your logic  
           ;
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签