ThreadStatic应用(Identity补完)

 

关于Identity

Identity自增序列/唯一断标识

起初做这个东西,是在一个内部组件中,用于在高并发的环境下得到一个较短的“相对”不重复标识字符串;(这里说的相对是指一定的数量下不重复)

灵感自然是来自于SqlServer的自增列和@@Identity变量

困扰

但是自从做完之后就有一个问题困扰这我,就是这个Current属性,这个属性的实用性其实非常的差

因为在高并发的环境中,使用Next()之后,即使立即使用Current属性得到的也是一个新的值,这点来说跟SqlServer的@@Identity是完全不同的

@@Identity的值无论并发多严重,你在同一个语句,或者说同一次会话中是不会改变的,除非该次会话新增了记录

(最近用了Oracle的序列对象,其中的sequence.CurrVal和@@Identity是一样的)

由于一直没有好的解决方案,而且没有这个功能不会影响这个类的使用,由于本身简单不需要维护,所以就渐渐遗忘了。

发现

昨日无意间发现了StaticThreadAttribute这个特性,MSDN官方文档对其的描述是:

用 ThreadStaticAttribute 标记的 static 字段不在线程之间共享。 每个执行线程都有单独的字段实例,并且独立地设置及获取该字段的值。 如果在不同的线程中访问该字段,则该字段将包含不同的值。

看了说明之后,我立即想起了这个被遗忘在角落的对象。逐动手改造

修改代码

using System;

namespace blqw
{
/// <summary> 自增序列,最大0xFFFFFFF,超过0xFFFFFFF回归1
/// </summary>
public static class Identity
{
[ThreadStatic]
static int? _ThreadCurrentId; static int _StaticId = 0;
/// <summary> 当前值
/// </summary>
public static int Current
{
get { return _ThreadCurrentId.GetValueOrDefault(-1); }
}
/// <summary> 当前值的String形式
/// </summary>
public static string CurrentString
{
get
{
if (_ThreadCurrentId.HasValue)
{
return GetString(_ThreadCurrentId.Value);
}
else
{
return null;
}
}
}
/// <summary> 获取一个id,每获取一次就会自增1,该方法在所有线程都是安全的
/// </summary>
public static int Next()
{
int i = System.Threading.Interlocked.Increment(ref _StaticId);
_ThreadCurrentId = _StaticId;
if (i > (0xFFFFFFF))
{
i = i - 0xFFFFFFF;
System.Threading.Interlocked.Exchange(ref _StaticId, i);
}
return i;
} //字符字典
static char[] _CharMap = new[]
{
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
}; /// <summary> 获取一个id的String表示形式,每获取一次就会自增1,该方法在所有线程都是安全的
/// </summary>
public static string NextString()
{
int number = Next();
return GetString(number);
} public static string GetString(int number)
{
if (number < 0)
{
throw new ArgumentOutOfRangeException("number", "number不能小于0");
}
int length = (int)Math.Log(number, 52) + 1;//52比较合理,不要改了
char[] c = new char[length];
for (int i = length - 1; i > 0; i--)
{
c[i] = _CharMap[number % 52];
number = number / 52;
}
c[0] = _CharMap[number];
return new string(c);
}
}
}

测试

for (int i = 0; i < 10; i++)
{
new Thread(o =>
{
Console.WriteLine(o + " > Init: " + Identity.Current);
Thread.Sleep(1100);
Console.WriteLine(o + " > Next: " + Identity.Next());
Thread.Sleep(100);
Console.WriteLine(o + " > Curr: " + Identity.Current);
Thread.Sleep(100);
Console.WriteLine(o + " > NStr: " + Identity.NextString());
Thread.Sleep(100);
Console.WriteLine(o + " > Curr: " + Identity.Current);
}).Start(i);
Thread.Sleep(100);
}

测试代码比较简单,开10个线程,让他们交错运行就行了

先上一个没有标记StaticThread的结果

把StaticThread注释掉运行,可以看到结果 在0号线程中使用Next得到值1 然后使用Current却得到2 ,因为在1号线程中调用Next影响了Current的值

这就是原来的效果,所以之前使用的时候都是 int i = Identity.Next() ;然后就拿 i 使用了

现在加在StaticThread

可以看到,现在线程0中的Current属性的值,并不会受到其他线程的影响了

总结

StaticThread特性允许我们将一个静态的变量的值在不同线程中是独立的

这个特性在某些情况下还是非常好用的

比如web应用中,每个请求都是一个独立的线程,如果我们希望将一个值作为静态字段全局使用,同时又不想影响其他用户,这时候一般我们是使用Session的

现在就可以有第二种选择了

Session可以将一个值长时间的保存,不于局限一次请求,但是Session需要应用System.Web.dll

StaticThread可以直接指定一个静态变量,但仅只能是当前请求,请求总段值就丢了

可以更新需要选择使用

最后,不知道StaticThread会不会带来额外的性能问题,希望知道的朋友可以告知

code

https://code.csdn.net/snippets/104950

我写的文章,除了纯代码,其他的都是想表达一种思想,一种解决方案.希望各位看官不要局限于文章中的现成的代码,要多关注整个文章的主题思路,谢谢!

我发布的代码,没有任何版权,遵守WTFPL协议(如有引用,请遵守被引用代码的协议)

手把手教你使用FineUI开发一个b/s结构的取送货管理信息系统(附源码+视频教程(1,2节))

 

一 本系列随笔概览及产生的背景

近阶段接到一些b/s类型的软件项目,但是团队成员之前大部分没有这方面的开发经验,于是自己选择了一套目前网上比较容易上手的开发框架(FineUI),计划录制一套视频讲座,来讲解如何利用FineUI快速开发一个小型的b/s结构的管理系统,已达到帮助团队成员快速掌握b/s结构信息系统的开发方法。

源码位置:https://github.com/kamiba/FineUIDemo

源码下载办法:安装SVN客户端(本文最后提供下载地址),然后checkout以下的地址:https://github.com/kamiba/FineUIDemo.git

初学者应先下载源代码,然后对照视频,一步一步跟着做。

演示地址:http://42.121.4.78:8055/ 用户名和密码 均为admin

作者计划将本系列博文+视频做成一个Step by Step系列,请初级读者关注,高手绕道。目录拟定如下:

1.使用FineUI搭建系统基本框架

2.系统需求及数据库设计

3.加工人员,产品,产品分类等基础信息管理(如何使用FineUI进行增删改查)

4.取货管理,送货管理,取送货统计,支付管理,支付统计(grid控件,分页,数据表查询)

5.将取送货管理系统整合进AppBox2.0(AppBox是使用FineUI开发的开源的通用权限管理框架,目前最新版本是3.0)。

二 为什么采用视频的方式讲解

缺点:

1.不利于SEO。

优点:

1.视频的方式相对写技术博文的效率更高(语音比文字在同样的时间内可以传达更多的信息);

2.讲述内容的性质决定的(这个系列的视频是从头开始讲解一个小型web系统是如何开发出来的,虽然没有什么高深的技术,但是涉及到很多开发中常用的技巧,比较适合初学者。采用视频的方式可以更加详细的把这些细节内容展现出来)。

三 不仅仅是FineUI

视频中,除了讲解FineUI的基本使用技巧之外,介绍了很多初级开发人员不是很理解但却十分重要的知识。比如数据库表的设计与查询方法,cookie的用法,表格的分页,程序集,添加引用,命名空间,postback表单回传的概念等等。

四 前2节视频内容简介

第一节 使用FineUI搭建系统基本框架

1.空web项目的创建;

2.登录对话框(登录成功后如何自动跳转到主界面,Cookie的运用,以使得服务器记录用户的认证状态);

3.主界面布局的讲解(Top Region,left Region,main Region,tree控件,TabStrip控件)。

4.模块配置文件(menu.xml)。

第二节 系统需求及数据库设计

1.系统需求分析

2.数据库表的创建(数据库的设计方法,如何保证数据的完整性和一致性,数据库设计中应该注意的问题)

3.动软代码生成器的使用(如何连接数据库,生成三层代码)

4.将动软代码生成器生成的代码合并到项目中

五 前两节视频下载地址及常用工具下载地址

1.FineUI+动软代码生成器开发一个b/s结构的取送货管理信息系统第一节

2.FineUI+动软代码生成器开发一个b/s结构的取送货管理信息系统第二节

3.动软代码生成器V2.41安装包

4.SVN客户端安装包

 
 
分类: C#

Identity的更多相关文章

  1. ASP.NET Core 之 Identity 入门(一)

    前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...

  2. ASP.NET Core 之 Identity 入门(三)

    前言 在上一篇文章中,我们学习了 CookieAuthentication 中间件,本篇的话主要看一下 Identity 本身. 最早2005年 ASP.NET 2.0 的时候开始, Web 应用程序 ...

  3. ASP.NET Core 之 Identity 入门(二)

    前言 在 上篇文章 中讲了关于 Identity 需要了解的单词以及相对应的几个知识点,并且知道了Identity处在整个登入流程中的位置,本篇主要是在 .NET 整个认证系统中比较重要的一个环节,就 ...

  4. 从Membership 到 .NET4.5 之 ASP.NET Identity

    我们前面已经讨论过了如何在一个网站中集成最基本的Membership功能,然后深入学习了Membership的架构设计.正所谓从实践从来,到实践从去,在我们把Membership的结构吃透之后,我们要 ...

  5. TSQL Identity 用法全解

    Identity是标识值,在SQL Server中,有ID列,ID属性,ID值,ID列的值等术语. Identity属性是指在创建Table时,为列指定的Identity属性,其语法是:column_ ...

  6. MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN

    在Membership系列的最后一篇引入了ASP.NET Identity,看到大家对它还是挺感兴趣的,于是来一篇详解登录原理的文章.本文会涉及到Claims-based(基于声明)的认证,我们会详细 ...

  7. ASP.NET Identity入门系列教程(一) 初识Identity

    摘要 通过本文你将了解ASP.NET身份验证机制,表单认证的基本流程,ASP.NET Membership的一些弊端以及ASP.NET Identity的主要优势. 目录 身份验证(Authentic ...

  8. 列属性:RowGUIDCol、Identity 和 not for replication

    Table Column有两个特殊的属性RowGUIDCol 和 Identity,用于标记数据列: $ROWGUID 用于引用被属性 RowGUIDCol 标识的UniqueIdentifier 类 ...

  9. SQL Server 合并复制遇到identity range check报错的解决

        最近帮一个客户搭建跨洋的合并复制,由于数据库非常大,跨洋网络条件不稳定,因此只能通过备份初始化,在初始化完成后向海外订阅端插入数据时发现报出如下错误: Msg 548, Level 16, S ...

  10. 坎坷路:ASP.NET Core 1.0 Identity 身份验证(中集)

    上一篇:<坎坷路:ASP.NET 5 Identity 身份验证(上集)> ASP.NET Core 1.0 什么鬼?它是 ASP.NET vNext,也是 ASP.NET 5,以后也可能 ...

随机推荐

  1. 一对TCP协议及OSI简介模式

    原文地址:  移步这里

  2. 第6章 适配器模式(Adapter Pattern)

    原文 第6章 适配器模式(Adapter Pattern) 概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作.  解决的问 ...

  3. 两个div横向排列,顶端对齐的方式。

    1.左右两个div都设置为float:left,如果右边div没有设置宽度,右边div的宽度会根据div里的内容自动调整. <!DOCTYPE html PUBLIC "-//W3C/ ...

  4. c#中 ==与equals有什么区别

    对于值类型.引用类型来说比较过程怎样的? using System;using System.Collections.Generic;using System.Text; namespace Cons ...

  5. 线程同步synchronized

    一Java规划共享多个线程之间数据的能力. 当线程以异步方式訪问共享数据时.有时候是不安全的或者不和逻辑的. 比方卖火车票.同一时刻一个线程在读取数据,另外一个线程在处理数据,当处理数据的线程没有等到 ...

  6. String不变性

    String不变性理解类型: String x = "java"; System.out.println(x);//输出为java x.concat("java" ...

  7. Log4j2 简明教程

    一.概述 log4j2官方文档内容非常多,要一次性了解全部是不可能的.正确的步骤应当是先了解最常见的配置,当发现原有知识无法解决问题,再重新查看文档看有没有合适的配置.下面将从文件结构入手,再到简单的 ...

  8. hdu2191 悼念512汶川大地震遇难同胞——珍惜如今,感恩生活

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191 Problem ...

  9. Vim实用小技巧

    Vim实用小技巧 一些网络上质量较高的Vim资料 从我07年接触Vim以来,已经过去了8个年头,期间看过很多的Vim文章,我自己觉得非常不错,而且创作时间也比较近的文章有如下这些. Vim入门 目前为 ...

  10. SURF分析算法

    SURF分析算法 一个.整体形象     这个概念是积分图像Viola和Jones建议.随机位积分图像(i.j)的值原始图象的左上角随机点(i,j)级配相应的重点领域值的总和,其数学公式如图1所看到的 ...