一个客户端向服务器端socket发送报文,但是服务器端限制了发送频率,假如10秒内只能发送1次,这时客户端也要相应的做限制,初步的想法是在配置文件中保存上次最后发送的时间,当前发送时和这个上次最后时间做比较,根据情况马上发送还是休眠相应的时间。
举个例子,服务器发送频率限制是10秒,上次最后发送时间是10:00:00,有两种情况:
(1)当前时间是10:00:03,则过7秒后发送;
(2)当前时间是10:02:00,则马上发送。
App.config

<!--发送频率限制(秒)-->
<add key="MsgTimeLimit" value="10"/>
<!--上次最后发送时间-->
<add key="LastMsgTime" value="2013-11-1"/>

Test.cs

CancellationTokenSource ct;
private void btnOK_Click(object sender, EventArgs e)
{
btnOK.Enabled = false; Task t = new Task(() => Do(ct));
ct = new CancellationTokenSource();
t.Start();
t.ContinueWith((x) =>
{
this.SafeCall(() =>
{
richTextBox1.AppendText("任务结束\r\n");
btnOK.Enabled = true;
});
});
}
private void btnCancel_Click(object sender, EventArgs e)
{
ct.Cancel();
}
private void Do(CancellationTokenSource ct)
{
for (int i = 0; i < 3; i++)
{
if (!ct.IsCancellationRequested)
{
int restSeconds = GetMsgRestSeconds();
if (restSeconds > 0)
{
SetTextBoxText("请等待,暂停 " + restSeconds + " 秒\r\n");
Thread.Sleep(restSeconds * 1000);
}
SetTextBoxText("正在发送第" + (i + 1).ToString() + "个客户...\r\n");
AppSettings.SetValue("LastMsgTime", DateTime.Now.ToString());
}
else
{
SetTextBoxText("任务" + (i + 1).ToString() + "取消\r\n");
}
}
}
/// <summary>
/// 获取发送剩余的时间
/// </summary>
/// <returns></returns>
private int GetMsgRestSeconds()
{
int msgTimeLimit = 0;
//获取要限制的间隔时间(秒)
int.TryParse(AppSettings.GetValue("MsgTimeLimit"), out msgTimeLimit);
if (msgTimeLimit == 0)
return 0;
//最近一次时间
string lastMsgTime = AppSettings.GetValue("LastMsgTime");
DateTime dtLastMsgTime = DateTime.MinValue;
DateTime.TryParse(lastMsgTime, out dtLastMsgTime);
DateTime dtNow = DateTime.Now;
if (dtLastMsgTime == DateTime.MinValue || dtLastMsgTime >= dtNow)
return 0;
TimeSpan ts = dtNow - dtLastMsgTime;
int restSeconds = 0;
if (msgTimeLimit > ts.TotalSeconds)
{
restSeconds = msgTimeLimit - (int)ts.TotalSeconds;
restSeconds = restSeconds < 0 ? 0 : restSeconds;
}
return restSeconds;
}

其中
AppSettings.SetValue()和AppSettings.GetValue()方法见:
http://blog.csdn.net/gdjlc/article/details/8284799

SafeCall是个扩展方法
public static void SafeCall(this Control ctrl, Action callback)
{
    if (ctrl.InvokeRequired)
        ctrl.Invoke(callback);
    else
        callback();
}

点击【确认】按钮执行结果如下:

正在发送第1个客户...
请等待,暂停 10 秒
正在发送第2个客户...
请等待,暂停 10 秒
正在发送第3个客户...
任务结束

过了3秒钟,点击【确认】按钮并在执行完第一个操作按【取消】执行结果如下:

请等待,暂停 7 秒
正在发送第1个客户...
请等待,暂停 10 秒
正在发送第2个客户...
任务3取消
任务结束

过了5秒钟,点击【确认】按钮执行结果如下:

请等待,暂停 5 秒
正在发送第1个客户...
请等待,暂停 10 秒
正在发送第2个客户...
请等待,暂停 10 秒
正在发送第3个客户...
任务结束

C#定时执行一个操作的更多相关文章

  1. 使用oracle 的 PL/Sql 定时执行一个存储过程

    CSDN日报20170322--<关于软件研发的一些体会总结> 同步博客至 CSDN ,让更多开发者看到你的文章 看微博技术大咖解析互联网应用架构实战 使用oracle 的 PL/Sql ...

  2. c# 定时启动一个操作、任务

    // 定时启动一个操作.任务 using System; using System.Collections.Generic; using System.Collections.ObjectModel; ...

  3. (原创)在service中定时执行网络操作的几点说明

    执行网络操作是耗时操作,即便是在service中也要放到子线程中执行 这里我用到了async-http-client框架来执行异步请求操作 计时用的java原生Timer和TimerTask类 本来这 ...

  4. Quartz.NET实现作业调度(3.0版本实现)定时执行一个任务

    2.0版本请参考https://www.cnblogs.com/best/p/7658573.html这里的文章很详细: 我们现在想每5秒钟往txt文件夹里存储一个时间 首先:定义一个类,实现Quar ...

  5. 在Windows里定时执行一个Python文件

    一.系统环境 操作系统:Win7 64位 二.说明 1.建立一个dos批处理文件 例: @echo off C: cd C:\work\python python aaa.py exit 2.利用Wi ...

  6. 最简单的???ubuntu 通过crontab定时执行一个程序

    crontab在liunx系统中下载,我默认是认为下载安装了的.. crontab貌似只能在liunx系统中存在,如果是windows系统我不知道 创建一个名为jiaoben的文件夹存储sh文件,进入 ...

  7. oracle定时执行一个存储过程

    首先需要新建存储过程 一 存储过程: create or replace procedure Insertdata is begin INSERT INTO tab_dayta select * fr ...

  8. android 定时执行一个任务

    1. timer = new Timer(true) TimerTask task =  new TimerTask(){ public void run(){ test(); } } timer.s ...

  9. java中定时执行任务

    现在项目中用到需要定时去检查文件是否更新的功能.timer正好用于此处. 用法很简单,new一个timer,然后写一个timertask的子类即可. 代码如下: package comz.autoup ...

随机推荐

  1. IOS第二天多线程-01-延时执行

    **********延时执行 #import "HMViewController.h" @interface HMViewController () @end @implement ...

  2. IOS第七天(3:UiTableView 模型和数据的分组的显示)

    *************UiTableView模型和数据的分组的显示 #import "HMViewController.h" #import "HMHero.h&qu ...

  3. C#抽象类、抽象方法、虚方法

    定义抽象类和抽象方法: abstract 抽象类特点: 1.不能初始化的类被叫做抽象类,它们只提供部分实现,但是另一个类可以继承它并且能创建它们的实例 2.一个抽象类可以包含抽象和非抽象方法,当一个类 ...

  4. Linux内存管理基本概念

    1. 基本概念 1.1 地址 (1)逻辑地址:指由程序产生的与段相关的偏移地址部分.在C语言指针中,读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址.( ...

  5. chmod() has been disabled for security reasons

    最近用 codeigniter 写一个小系统,引用了session 库,codeigniter默认的session存储方式为files.鉴于安全性,文件即肯定涉及到权限问题. 在类 UNIX 操作系统 ...

  6. C#异步编程简单的运用

    当一个方法中有很多复杂的操作的时候就可以使用异步编程. 假如说这一个方法中有很多复杂的操作,把每一个复杂的操作放到一个异步方法中. 原来程序需要这些方法,上一个执行完成之后,才能执行下一个操作. 但是 ...

  7. swift流行UI库(github)

    http://www.cocoachina.com/ios/20161109/18007.html

  8. 将编码从GB2312转成UTF-8的方法汇总(从前台、程序、数据库)

    这篇文章主要介绍了将编码从GB2312转成UTF-8的方法汇总(从前台.程序.数据库),需要的朋友可以参考下 一个网站如果需要国际化,就需要将编码从GB2312转成UTF-8,其中有很多的问题需要注意 ...

  9. RDIFramework.NET平台代码生成器V2.8发布-更新于2014-12-31(提供下载)

    RDIFramework.NET平台代码生成器V2.8发布  更新于2014-12-31 注:已经发布了新版本,请转新版本下载: RDIFramework.NET平台代码生成器V3.0版本全新发布-更 ...

  10. Go 模板

    原文链接 很多语言都有很多方式将字符串从一只形式转换成另一种形式.Go 使用模板的方法通过提供一个对象作为参数来转换字符串.这个一般来讲是用来将对象插入到HTML中的,不过它同样可以用在其他的情况下. ...