Winform 模拟Session
背景
在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的更多相关文章
- Winform模拟post请求和get请求登录网站
引言 最近有朋友问如何用winform模拟post请求,然后登录网站,稍微想了一下,大致就是对http报文的相关信息的封装,然后请求网站登录地址的样子.发现自己的博客中对这部分只是也没总结,就借着这股 ...
- Memcache+cookie实现模拟session
上一片讲到Memcached在Windows上的安装,和用Telnet工具进行命令操作,在稍微了解了原理之后,我也就开始尝试着用程序来对Memcached进行操作.这一篇分为两个部分,第一部分是用.n ...
- Python day15装饰器基本理论,以及结合全局变量模拟session
装饰器(decorator):为其他函数添加附加功能 原则:1.不修改被修饰函数源代码 2.不修改被修饰函数的调用方式 装饰器=高阶函数+函数嵌套+闭包 import time def timmer( ...
- 利用Node.js实现模拟Session验证的登陆
1.身份验证和用户登陆 在一般的Web应用上,假设要实现用户登陆,最经常使用,也是最简单的方法就是使用Session,主要的思路是在Session中保留一些用户身份信息,然后每次在Session中取, ...
- 通过winform+模拟登录实现快速一键登录到人才招聘网站
之前为了便于人事部门招聘登录网站更简洁高效,免去每天频繁输网址.用户名.密码等相关登录信息,特基于winform+HttpWebRequest实现模拟请求登录,最终达到一键登录到招聘网站后台的效果. ...
- sonar + jacoco + mockMvc 模拟session 用户登录 配合SpringSecurity 权限 快速测试代码覆盖率.
遇到mock 测试简直就是神器,特别是要做代码覆盖率,直接测试controller就好了,缺点,虽然可以回滚事务,但是依赖数据库数据,解决,根据SpringBoot ,再建立一个专门跑单元测试的数据库 ...
- python---cookie模拟登陆和模拟session原理
cookie模拟登陆: import tornado.web class IndexHandler(tornado.web.RequestHandler): def get(self): #self. ...
- winform实现Session功能(保存用户信息)
问题描述:在winform中想实现像BS中类似Session的功能,放上需要的信息,在程序中都可以访问到. 解决方案:由于自己很长时间没有做过winform的程序,一时间竟然手足无措起来.后来发现wi ...
- C# winform 模拟键盘鼠标操作
1.获取鼠标位置 private void timer1_Tick(object sender, EventArgs e) { // timer1.Stop(); // int x = Control ...
随机推荐
- mysql_old_wrong
DELIMITER $ create trigger auto_post_person_pointafter insert on post for each rowbeginupdate person ...
- 操作视频-对视频进行canny边缘检测
#include<opencv2/opencv.hpp> using namespace cv; int main() { VideoCapture capture(); //从摄像头读入 ...
- 16,docker入门
在学一门新知识的时候,超哥喜欢提问,why?what?how? wiki资料 什么是docker Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一 ...
- easyui js拼接html,class属性失效的问题
问题:要在前一个按钮之后添加相同的样式的按钮,通过$("#cj").html(str); 这样的形式添加,却不能添加上样式 <div id="btn" c ...
- 如何在一个顶级域名下用两个二级域名访问vps下的两个项目网站--完美解决骗
本人是原址是http://www.webzhe.com/server/340 后经过本人的实践修改,增加截图,等具体的步骤,完美解决 如何在vps中设置二级域名开通子网站,这个问题涉及到两步:一首先要 ...
- [转]grep 在文本中查找内容
转自: http://www.lampweb.org/linux/3/27.html 功能:grep系列是Linux中使用频率最高的文本查找命令.主要功能在一个或者多个文件中查找特定模式的字符串.如果 ...
- Django笔记 —— 视图
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...
- python学习笔记十一:操作mysql
一.安装MySQL-python # yum install -y MySQL-python 二.打开数据库连接 #!/usr/bin/python import MySQLdb conn = MyS ...
- nosetests
1.nosetests 执行出测试报告 提前安装 插件nose-html系列插件 nosetests -v --with-html-output --html-out-file=报告名.html ...
- Python全栈工程师(递归函数、闭包)
ParisGabriel 每天坚持手写 一天一篇 决定坚持几年 全栈工程师 Python人工智能从入门到精通 函数式编程: 是指用一系列函数解决问题 每一个函数完成细 ...