using System;
using System.Threading;
using System.Threading.Tasks;
enum State
{
Stopped,
Running,
Paused
}
interface IStateHandler
{
Task Handle(State currentState, CancellationToken cancellationToken);
}
class StoppedStateHandler : IStateHandler
{
public async Task Handle(State currentState, CancellationToken cancellationToken)
{
Console.WriteLine("Starting...");
await Task.Delay(1000, cancellationToken); // 使用 CancellationToken 控制超时
Console.WriteLine("Started.");
}
}
class RunningStateHandler : IStateHandler
{
public async Task Handle(State currentState, CancellationToken cancellationToken)
{
Console.WriteLine("Pausing...");
await Task.Delay(1000, cancellationToken);
Console.WriteLine("Paused.");
}
}
class PausedStateHandler : IStateHandler
{
public async Task Handle(State currentState, CancellationToken cancellationToken)
{
Console.WriteLine("Resuming...");
await Task.Delay(1000, cancellationToken);
Console.WriteLine("Resumed.");
}
}
class StateMachine
{
private State currentState;
private readonly IStateHandler[] stateHandlers;
public event EventHandler<State> StateChanged;
public StateMachine()
{
currentState = State.Stopped;
stateHandlers = new IStateHandler[Enum.GetValues(typeof(State)).Length];
stateHandlers[(int)State.Stopped] = new StoppedStateHandler();
stateHandlers[(int)State.Running] = new RunningStateHandler();
stateHandlers[(int)State.Paused] = new PausedStateHandler();
}
public async Task Start(CancellationToken cancellationToken)
{
await HandleStateTransition(State.Stopped, cancellationToken);
}
public async Task Pause(CancellationToken cancellationToken)
{
await HandleStateTransition(State.Running, cancellationToken);
}
public async Task Resume(CancellationToken cancellationToken)
{
await HandleStateTransition(State.Paused, cancellationToken);
}
public async Task Stop(CancellationToken cancellationToken)
{
await HandleStateTransition(State.Stopped, cancellationToken);
}
private async Task HandleStateTransition(State nextState, CancellationToken cancellationToken)
{
try
{
using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
{
linkedCts.CancelAfter(5000); // 设置操作超时时间为 5 秒钟
await stateHandlers[(int)nextState].Handle(currentState, linkedCts.Token);
currentState = nextState;
OnStateChanged();
}
}
catch (TaskCanceledException)
{
Console.WriteLine("Operation timed out.");
}
catch (Exception ex)
{
Console.WriteLine($"Error occurred: {ex.Message}");
}
}
protected virtual void OnStateChanged()
{
StateChanged?.Invoke(this, currentState);
}
}
class Program
{
static async Task Main(string[] args)
{
using (var cancellationTokenSource = new CancellationTokenSource())
{
StateMachine stateMachine = new StateMachine();
stateMachine.StateChanged += StateMachine_StateChanged;
await stateMachine.Start(cancellationTokenSource.Token);
await stateMachine.Pause(cancellationTokenSource.Token);
await stateMachine.Resume(cancellationTokenSource.Token);
await stateMachine.Stop(cancellationTokenSource.Token);
cancellationTokenSource.Cancel(); // 停止所有操作,包括超时的操作
}
Console.ReadLine();
}
private static void StateMachine_StateChanged(object sender, State e)
{
Console.WriteLine($"State changed: {e}");
}
}
1,引入了CancellationToken
和CancellationTokenSource
来控制操作超时。
2,在HandleStateTransition
方法中,我们创建一个与传入的CancellationToken
关联的新的CancellationTokenSource
实例,并在其中设置超时时间。
3,使用linkedCts.Token
作为参数调用状态处理程序的Handle
方法,以便随时取消操作。如果操作超时或者被取消,我们可以捕获TaskCanceledException
并进行相应的处理。