欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > C# 的异步任务中, 如何暂停, 继续,停止任务

C# 的异步任务中, 如何暂停, 继续,停止任务

2025/5/13 23:11:06 来源:https://blog.csdn.net/helldoger/article/details/147832861  浏览:    关键词:C# 的异步任务中, 如何暂停, 继续,停止任务
namespace taskTest
{using System;using System.Threading;using System.Threading.Tasks;public class MyService{private Task? workTask;private readonly SemaphoreSlim semaphore = new SemaphoreSlim(0, 1); // 初始为 0,Start() 启动时手动放行private readonly CancellationTokenSource cts = new CancellationTokenSource();private volatile bool autoReleaseSemaphore = true; // 控制 ProcessAsync 是否自动 Releasepublic void Start(){Console.WriteLine("Starting service");autoReleaseSemaphore = true;semaphore.Release(); // 初始启动一次workTask = Task.Run(() => TreadJob(cts.Token));Console.WriteLine("Service started, task ID: " + workTask.Id);}public void Pause(){Console.WriteLine("Pausing service...");autoReleaseSemaphore = false; // 禁止 ProcessAsync 自动 Release}public void Resume(){Console.WriteLine("Resuming service...");autoReleaseSemaphore = true; // 允许 ProcessAsync 自动 Releasesemaphore.Release(); // 手动触发一次 Release,唤醒阻塞的 WaitAsync}public void Stop(){Console.WriteLine("Stopping service...");cts.Cancel();}private async Task TreadJob(CancellationToken token){Console.WriteLine("TreadJob started...");try{if (!cts.IsCancellationRequested){Console.WriteLine("Working...");await ProcessAsync(token);}}catch (OperationCanceledException e){Console.WriteLine(e.Message);Console.WriteLine("Service stopped");}}private async Task ProcessAsync(CancellationToken token){for (int i = 0; i < 100; i++){await semaphore.WaitAsync(token); // 等待信号量token.ThrowIfCancellationRequested();await Task.Delay(500, token);if (autoReleaseSemaphore){semaphore.Release(); // 只有当 autoReleaseSemaphore 为 true 时才 Release}else{continue;}Console.WriteLine($"Process.{i}");}}}
}
namespace taskTest
{internal class Program{static void Main(string[] args){MyService service = new();service.Start();// 等待一段时间,确保 ProcessAsync 有机会执行Console.ReadLine();//Thread.Sleep(1500);// 暂停服务service.Pause();Console.WriteLine("暂停了");Console.WriteLine("按下回车启动Resume");Console.ReadLine();Console.WriteLine("ReadLine执行完");service.Resume();Console.ReadLine();service.Stop();Console.ReadLine();}}
}

结果:

在这里插入图片描述

在PLC中的应用:

using S7.Net;
using System.Reflection;namespace taskTest
{public class S7ConnServiceImpl : IS7ConnService{public S7ConnServiceImpl(Db95DeviceHis db95DeviceHis){this.db95DeviceHis = db95DeviceHis;}private static readonly object lockObj = new object(); // 创建一个对象作为锁private Db95DeviceHis db95DeviceHis;private bool myIsConnected = false;private int errorTimes = 0;private CancellationTokenSource cts = new();private readonly SemaphoreSlim semaphore = new SemaphoreSlim(0, 1); // 初始为 0,Start() 启动时手动放行private volatile bool autoReleaseSemaphore = true; // 控制 ProcessAsync 是否自动 Releasepublic bool MyIsConnected{get => myIsConnected;set => myIsConnected = value;}private Plc? s7Plc = null;public Plc? S7Plc => s7Plc;public void ConnPlc(string myIp, int dbNum, int startByte){return;}public void ConnPlc(string myIp){autoReleaseSemaphore = true;semaphore.Release(); // 初始启动一次try{Task.Factory.StartNew(async () =>{while (!cts.IsCancellationRequested){if (s7Plc == null || !MyIsConnected){try{s7Plc = new Plc(CpuType.S71500, myIp, 0, 1);s7Plc.Open();s7Plc.ReadTimeout = 620;s7Plc.WriteTimeout = 620;//ctsRead1 = new();//ctsRead2 = new();MyIsConnected = s7Plc.IsConnected;if (MyIsConnected){Console.WriteLine("PlcSucessConn!");}}catch (PlcException ex){errorTimes++;s7Plc.Close();s7Plc = null;MyIsConnected = false;Console.WriteLine(ex.Message);Console.WriteLine("连接发生错误");Console.WriteLine(ex.GetType().Name);Console.WriteLine("ErrorsTime:" + errorTimes);await Task.Delay(2000);}}else if (MyIsConnected){try{MyIsConnected = s7Plc.IsConnected;await semaphore.WaitAsync(cts.Token); // 等待信号量cts.Token.ThrowIfCancellationRequested();await Task.Delay(200);errorTimes = 0;if (autoReleaseSemaphore){semaphore.Release(); // 只有当 autoReleaseSemaphore 为 true 时才 Release}else{continue;}var tempDb95DeviceHis =await S7Plc.ReadClassAsync<Db95DeviceHis>(95, 0);lock (lockObj){if (tempDb95DeviceHis != null){CopyProperties(tempDb95DeviceHis, db95DeviceHis);}Console.WriteLine(db95DeviceHis.Kr500Trigger);Console.WriteLine(db95DeviceHis.Kr16Time);}}catch (IOException ex){errorTimes++;await Task.Delay(2000);Console.WriteLine("读取发生错误");Console.WriteLine(ex.GetType().Name);Console.WriteLine($"读取时发生错误:{ex.Message}");Console.WriteLine($"读取时发生错误次数:{errorTimes}");s7Plc.Close();MyIsConnected = false;s7Plc = null;}}}},cts.Token,TaskCreationOptions.LongRunning,TaskScheduler.Default);}catch (OperationCanceledException e){Console.WriteLine(e.Message);Console.WriteLine("Service stopped");}}public void Pause(){Console.WriteLine("Pausing service...");autoReleaseSemaphore = false; // 禁止 ProcessAsync 自动 Release}public void Resume(){Console.WriteLine("Resuming service...");autoReleaseSemaphore = true; // 允许 ProcessAsync 自动 Releasesemaphore.Release(); // 手动触发一次 Release,唤醒阻塞的 WaitAsync}public void Stop(){Console.WriteLine("Stopping service...");cts.Cancel();}/// <summary>/// 反射复制属性值/// </summary>/// <param name="source"></param>/// <param name="destination"></param>/// <exception cref="ArgumentNullException"></exception>public void CopyProperties(object source, object destination){if (source == null || destination == null){throw new ArgumentNullException("Either source or destination is null.");}Type sourceType = source.GetType();Type targetType = destination.GetType();foreach (PropertyInfo sourceProperty in sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance)){PropertyInfo targetProperty = targetType.GetProperty(sourceProperty.Name);if (targetProperty != null&& targetProperty.CanWrite&& sourceProperty.PropertyType == targetProperty.PropertyType){targetProperty.SetValue(destination, sourceProperty.GetValue(source));}}}}
}
    public class Db95DeviceHis : INotifyPropertyChanged{public int Ret { get; set; }public float Kr16Time { get; set; }public float Kr500Time { get; set; }public float Dizuo1Time { get; set; }public float Dizuo2Time { get; set; }public float Dizuo3Time { get; set; }public float Kj1Time { get; set; }public float Kj2Time { get; set; }public float Kj3Time { get; set; }public float ZhouTime { get; set; }public float DamoTime { get; set; }public bool Kr16Trigger{get => kr16Trigger;set{if (kr16Trigger != value && value == true){NotifyPropertyChanged();}kr16Trigger = value;}}public bool Kr500Trigger{get => kr500Trigger;set{if (kr500Trigger != value && value == true){NotifyPropertyChanged();}kr500Trigger = value;}}private bool kr16Trigger;private bool kr500Trigger;public virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = ""){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}public event PropertyChangedEventHandler? PropertyChanged;}
    public interface IS7ConnService{void ConnPlc(string myIp, int dbNum, int startByte);void ConnPlc(string myIp);bool MyIsConnected{get;}Plc? S7Plc { get; }}

program主程序

        static void Main(string[] args){S7ConnServiceImpl serviceImpl = new(new Db95DeviceHis());serviceImpl.ConnPlc("192.168.2.10");Console.ReadLine();serviceImpl.Pause();Console.ReadLine();serviceImpl.Resume();Console.ReadLine();serviceImpl.Pause();Console.ReadLine();serviceImpl.Resume();Console.ReadLine();serviceImpl.Stop();Console.ReadLine();//MyService service = new();//service.Start(); 等待一段时间,确保 ProcessAsync 有机会执行//Console.ReadLine();Thread.Sleep(1500); 暂停服务//service.Pause();//Console.WriteLine("暂停了");//Console.WriteLine("按下回车启动Resume");//Console.ReadLine();//Console.WriteLine("ReadLine执行完");//service.Resume();//Console.ReadLine();//service.Stop();//Console.ReadLine();}

结果:
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词