背景

  在Web中Session的功能很好用,于是想Winform中实现该功能,典型应用场景则是登陆成功后,当一段时间不操作,则该会话过期,提示重新登陆。

资源下载

  测试代码

  示例说明:登陆进去10s不操作或者访问Cache后10秒不操作,则会提示登陆超时

实现

  1. 设计CacheContainer类,使用Dictionary存放变量,并添加互斥锁SyncRoot,避免多线程操作带来异常。

  2. CacheContainer内部的变量,如果持续10秒(测试使用的默认值)没有访问或操作,则自动移除该变量,并触发回调。

  3. 当程序访问CacheContainer内部的变量,过期时间从当前时间开始计时。

  4. 变量第一次计时在加入CacheContainer时。

  具体代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading; namespace WindowsFormsApplication1
{
public sealed class CacheContainer
{
//互斥锁
private object SyncRoot = new object();
//对象字典
private Dictionary<string, CacheObj> dic = new Dictionary<string, CacheObj>(); internal class CacheObj : IDisposable
{
//公有变量
public object Value { get; set; }
public int Expired { get; set; }
public WaitCallback callback { get; set; }
public AutoResetEvent ar = new AutoResetEvent(false);
public TimeSpan Timeout
{
get
{
return TimeSpan.FromSeconds(Expired);
}
}
public CacheObj(object value, int expired = )
{
Value = value;
Expired = expired;
callback = new WaitCallback((obj) =>
{
Console.WriteLine("{0}:已过期,过期时间:{1}", obj, DateTime.Now);
});
} public void Dispose()
{
GC.SuppressFinalize(this);
} ~CacheObj()
{
Dispose();
}
} private static CacheContainer container = new CacheContainer();
private CacheContainer() { }
public static CacheContainer GetInstance() { return container; } public object this[string key]
{
get
{
//访问变量成功,则时间重新计时
CacheObj cache;
lock (SyncRoot)
{
if (dic.TryGetValue(key, out cache))
{
cache.ar.Set();
return cache.Value;
}
}
return null;
}
set
{
//通过属性添加参数,有则覆盖,无则添加,操作完毕重新计时
CacheObj cache;
lock (SyncRoot)
{
if (dic.TryGetValue(key, out cache))
{
cache.Value = value;
cache.ar.Set();
}
else
Add(key, value);
}
}
} public void Add(string key, object value)
{
lock (SyncRoot)
dic.Add(key, new CacheObj(value));
AutoCheck(key);
} public void Add(string key, object value, int expired)
{
lock (SyncRoot)
dic.Add(key, new CacheObj(value, expired));
AutoCheck(key);
} public void Add(string key, object value, int expired, WaitCallback callback)
{
lock (SyncRoot)
dic.Add(key, new CacheObj(value, expired) { callback = callback });
AutoCheck(key);
} private void AutoCheck(string key)
{
//开启一个子线程去控制变量的过期
ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
{
CacheObj tmpCache;
while (true)
{
//从字典中取出对象
lock (SyncRoot)
tmpCache = dic[key];
//打印变量过期时间
Console.WriteLine("{0} 等待销毁变量 时间为:{1}秒", DateTime.Now, tmpCache.Expired);
//记录开始时间
var timeStart = DateTime.Now;
//中断,超时时间一到,自动向下执行
tmpCache.ar.WaitOne(TimeSpan.FromSeconds(tmpCache.Expired));
//检查时间是否已经达到超时时间,超时则移除该信息,并触发回调
if ((DateTime.Now - timeStart) >= tmpCache.Timeout)
{
lock (SyncRoot)
dic.Remove(key);
if (tmpCache.callback != null) tmpCache.callback(tmpCache.Value);
break;
}
}
}));
} public void Remove(string key)
{
lock (SyncRoot)
{
CacheObj cache;
if (dic.TryGetValue(key, out cache))
{
cache.Expired = ;
cache.ar.Set();
}
}
}
}
}

问题  

  CacheContainer中的变量,均是在线程池里有个线程去检测它,也就是说有10个变量,线程池里就会多10个子线程,这样会不会不太好。

  该方法仅是抛砖引玉,不知道在Winform中实现缓存变量xx分钟这样的功能有没有更好的方法,欢迎赐教,谢谢!

Winform 模拟Session的更多相关文章

  1. Winform模拟post请求和get请求登录网站

    引言 最近有朋友问如何用winform模拟post请求,然后登录网站,稍微想了一下,大致就是对http报文的相关信息的封装,然后请求网站登录地址的样子.发现自己的博客中对这部分只是也没总结,就借着这股 ...

  2. Memcache+cookie实现模拟session

    上一片讲到Memcached在Windows上的安装,和用Telnet工具进行命令操作,在稍微了解了原理之后,我也就开始尝试着用程序来对Memcached进行操作.这一篇分为两个部分,第一部分是用.n ...

  3. Python day15装饰器基本理论,以及结合全局变量模拟session

    装饰器(decorator):为其他函数添加附加功能 原则:1.不修改被修饰函数源代码 2.不修改被修饰函数的调用方式 装饰器=高阶函数+函数嵌套+闭包 import time def timmer( ...

  4. 利用Node.js实现模拟Session验证的登陆

    1.身份验证和用户登陆 在一般的Web应用上,假设要实现用户登陆,最经常使用,也是最简单的方法就是使用Session,主要的思路是在Session中保留一些用户身份信息,然后每次在Session中取, ...

  5. 通过winform+模拟登录实现快速一键登录到人才招聘网站

    之前为了便于人事部门招聘登录网站更简洁高效,免去每天频繁输网址.用户名.密码等相关登录信息,特基于winform+HttpWebRequest实现模拟请求登录,最终达到一键登录到招聘网站后台的效果. ...

  6. sonar + jacoco + mockMvc 模拟session 用户登录 配合SpringSecurity 权限 快速测试代码覆盖率.

    遇到mock 测试简直就是神器,特别是要做代码覆盖率,直接测试controller就好了,缺点,虽然可以回滚事务,但是依赖数据库数据,解决,根据SpringBoot ,再建立一个专门跑单元测试的数据库 ...

  7. python---cookie模拟登陆和模拟session原理

    cookie模拟登陆: import tornado.web class IndexHandler(tornado.web.RequestHandler): def get(self): #self. ...

  8. winform实现Session功能(保存用户信息)

    问题描述:在winform中想实现像BS中类似Session的功能,放上需要的信息,在程序中都可以访问到. 解决方案:由于自己很长时间没有做过winform的程序,一时间竟然手足无措起来.后来发现wi ...

  9. C# winform 模拟键盘鼠标操作

    1.获取鼠标位置 private void timer1_Tick(object sender, EventArgs e) { // timer1.Stop(); // int x = Control ...

随机推荐

  1. PLC状态机编程-如何在STL中使用状态机

    搞PLC编程多年,一直不知道状态机,学习matlab后,发现状态机编程异常方便,过去很多编程时的疑惑豁然开朗起来.今天跟大家分享一下如何在STL中使用状态机. 下面是用状态机描述的控制任务. 这个状态 ...

  2. Python系列6之面向对象

    目录 生成器和迭代器 字符串格式化 内置函数vars 反射 面向对象编程 一. 生成器和迭代器  1. 生成器 生成器具有一种生成的能力,它仅仅代表着一种生成的能力,当我们需要使用的时候,才会通过迭代 ...

  3. POJ 3581 三段字符串(后缀数组)

    Sequence Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7923   Accepted: 1801 Case Tim ...

  4. 汉罗塔问题——Python

    汉罗塔问题就是一个循环的过程:* (有两种情况) 如果被移动盘只有一个盘子,可以直接移动到目的盘 但是被移动盘有多个盘子,就先需要将上面的n-1个盘子通过目的盘移动到辅助盘,然后将被移动盘最下面一个盘 ...

  5. C# 控件置于最顶层、最底层、隐藏、显示

    控件置于最顶层.最底层 pictureBox1.BringToFront();//将控件放置所有控件最前端 pictureBox1.SendToBack();//将控件放置所有控件最底端 控件隐藏.显 ...

  6. 7-1 寻找大富翁 PTA 堆排序

    7-1 寻找大富翁 (25 分) 胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人.假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁. 输入格式: 输入首 ...

  7. 机器学习笔记(一)—— 线性回归问题与Matlab求解

    给你多组数据集,例如给你很多房子的面积.房子距离市中心的距离.房子的价格,然后再给你一组面积. 距离,让你预测房价.这类问题称为回归问题. 回归问题(Regression) 是给定多个自变量.一个因变 ...

  8. python基础之内置函数补充、匿名函数、递归函数

    内置函数补充 python divmod()函数:把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b) 语法: 1 divmod(a, b) #a.b为数字,a为除数 ...

  9. JVM——参数设置、分析

    原文:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html 不管是YGC还是Full GC,GC过程中都会对导致程序运行中中断 ...

  10. 5 Django-1的路由层(URLconf)

    URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码 ...