152 lines
4.4 KiB
C#
152 lines
4.4 KiB
C#
|
//----------------------------------------------------------------
|
|||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
//----------------------------------------------------------------
|
|||
|
|
|||
|
namespace System.Activities.DurableInstancing
|
|||
|
{
|
|||
|
using System;
|
|||
|
using System.Runtime;
|
|||
|
using System.Runtime.DurableInstancing;
|
|||
|
|
|||
|
abstract class PersistenceTask
|
|||
|
{
|
|||
|
bool automaticallyResetTimer;
|
|||
|
AsyncCallback commandCompletedCallback;
|
|||
|
InstancePersistenceCommand instancePersistenceCommand;
|
|||
|
TimeSpan taskInterval;
|
|||
|
IOThreadTimer taskTimer;
|
|||
|
object thisLock;
|
|||
|
bool timerCancelled;
|
|||
|
TimeSpan taskTimeout;
|
|||
|
|
|||
|
public PersistenceTask(SqlWorkflowInstanceStore store, SqlWorkflowInstanceStoreLock storeLock, InstancePersistenceCommand instancePersistenceCommand, TimeSpan taskInterval, TimeSpan taskTimeout, bool automaticallyResetTimer)
|
|||
|
{
|
|||
|
this.automaticallyResetTimer = automaticallyResetTimer;
|
|||
|
this.commandCompletedCallback = Fx.ThunkCallback(CommandCompletedCallback);
|
|||
|
this.instancePersistenceCommand = instancePersistenceCommand;
|
|||
|
this.Store = store;
|
|||
|
this.StoreLock = storeLock;
|
|||
|
this.SurrogateLockOwnerId = this.StoreLock.SurrogateLockOwnerId;
|
|||
|
this.taskInterval = taskInterval;
|
|||
|
this.thisLock = new object();
|
|||
|
this.taskTimeout = taskTimeout;
|
|||
|
}
|
|||
|
|
|||
|
protected SqlWorkflowInstanceStore Store
|
|||
|
{
|
|||
|
get;
|
|||
|
set;
|
|||
|
}
|
|||
|
|
|||
|
protected SqlWorkflowInstanceStoreLock StoreLock
|
|||
|
{
|
|||
|
get;
|
|||
|
set;
|
|||
|
}
|
|||
|
|
|||
|
protected long SurrogateLockOwnerId
|
|||
|
{
|
|||
|
get;
|
|||
|
set;
|
|||
|
}
|
|||
|
|
|||
|
object ThisLock
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return this.thisLock;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void CancelTimer()
|
|||
|
{
|
|||
|
lock (ThisLock)
|
|||
|
{
|
|||
|
this.timerCancelled = true;
|
|||
|
|
|||
|
if (this.taskTimer != null)
|
|||
|
{
|
|||
|
this.taskTimer.Cancel();
|
|||
|
this.taskTimer = null;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void ResetTimer(bool fireImmediately)
|
|||
|
{
|
|||
|
this.ResetTimer(fireImmediately, null);
|
|||
|
}
|
|||
|
|
|||
|
public virtual void ResetTimer(bool fireImmediately, TimeSpan? taskIntervalOverride)
|
|||
|
{
|
|||
|
TimeSpan timeTillNextPoll = this.taskInterval;
|
|||
|
|
|||
|
if (taskIntervalOverride.HasValue)
|
|||
|
{
|
|||
|
if (taskIntervalOverride.Value < this.taskInterval)
|
|||
|
timeTillNextPoll = taskIntervalOverride.Value;
|
|||
|
}
|
|||
|
|
|||
|
lock (ThisLock)
|
|||
|
{
|
|||
|
if (!this.timerCancelled)
|
|||
|
{
|
|||
|
if (this.taskTimer == null)
|
|||
|
{
|
|||
|
this.taskTimer = new IOThreadTimer(new Action<object>(this.OnTimerFired), null, false);
|
|||
|
}
|
|||
|
|
|||
|
this.taskTimer.Set(fireImmediately ? TimeSpan.Zero : timeTillNextPoll);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
protected abstract void HandleError(Exception exception);
|
|||
|
|
|||
|
void CommandCompletedCallback(IAsyncResult result)
|
|||
|
{
|
|||
|
SqlWorkflowInstanceStoreAsyncResult sqlResult = (SqlWorkflowInstanceStoreAsyncResult) result;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
this.Store.EndTryCommand(result);
|
|||
|
|
|||
|
if (this.automaticallyResetTimer)
|
|||
|
{
|
|||
|
this.ResetTimer(false);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception exception)
|
|||
|
{
|
|||
|
if (Fx.IsFatal(exception))
|
|||
|
{
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
HandleError(exception);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void OnTimerFired(object state)
|
|||
|
{
|
|||
|
if (this.StoreLock.IsLockOwnerValid(this.SurrogateLockOwnerId))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
this.Store.BeginTryCommandSkipRetry(null, this.instancePersistenceCommand, this.taskTimeout,
|
|||
|
this.commandCompletedCallback, null);
|
|||
|
}
|
|||
|
catch (Exception exception)
|
|||
|
{
|
|||
|
if (Fx.IsFatal(exception))
|
|||
|
{
|
|||
|
throw;
|
|||
|
}
|
|||
|
|
|||
|
this.HandleError(exception);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|