110,534
社区成员
发帖
与我相关
我的任务
分享
/// <summary>
/// 稿件编号驱动工厂
/// <para>稳定</para>
/// </summary>
public static class NumberProviderFactory
{
/// <summary>
/// 全局稿件编号驱动
/// </summary>
private static INumberProvider GlobalNumberProvider;
/// <summary>
/// 获取一个INumberProvider实例
/// <para>单例模式,全局唯一</para>
/// </summary>
/// <param name="configFilePath">文档配置文件路径</param>
/// <returns></returns>
public static INumberProvider GetNumberProvider(string configFilePath)
{
if (GlobalNumberProvider == null)
{
GlobalNumberProvider = new NumberProvider(configFilePath);
}
return GlobalNumberProvider;
}
}
/// <summary>
/// 稿件编号驱动接口
/// </summary>
public interface INumberProvider
{
/// <summary>
/// 访问线程计数器
/// </summary>
int VisitorCounter { get; }
/// <summary>
/// 获取当前串号
/// </summary>
/// <returns></returns>
int GetCurrent();
/// <summary>
/// 重置当前串号为0
/// </summary>
void Reset();
}
/// <summary>
/// 稿件编号驱动
/// </summary>
public class NumberProvider : INumberProvider
{
/// <summary>
/// xml配置文件的路径
/// </summary>
private string xmlPath = string.Empty;
/// <summary>
/// 单线程排它锁
/// </summary>
private Mutex AppLocker = new Mutex();
private int _VisitorCounter;
/// <summary>
/// 访问线程计数器
/// </summary>
public int VisitorCounter
{
get { return this._VisitorCounter; }
}
#region private int CurrentNumber { get; set; }
/// <summary>
/// 获取或设置当前串号
/// </summary>
private int CurrentNumber
{
get
{
try
{
XmlDocument xd = new XmlDocument();
xd.Load(xmlPath);
XmlNode xn = xd.SelectSingleNode("/document/numberseed/value");
if (xn != null)
return int.Parse(xn.InnerText);
return 0;
}
catch
{
return -1;
}
}
set
{
try
{
XmlDocument xd = new XmlDocument();
xd.Load(xmlPath);
XmlNode xn = xd.SelectSingleNode("/document/numberseed/value");
if (xn != null)
xn.InnerText = value.ToString();
xd.Save(xmlPath);
}
catch { }
}
}
#endregion
/// <summary>
/// 使用当前应用程序指定的配置文件计数
/// </summary>
/// <param name="configFilePath">文档配置文件路径</param>
public NumberProvider(string configFilePath)
{
if (string.IsNullOrEmpty(configFilePath))
this.xmlPath = HttpRuntime.AppDomainAppPath + "documentconf.xml";
else
this.xmlPath = configFilePath;
this._VisitorCounter = 0;
}
#region public virtual int GetCurrent()
/// <summary>
/// 获取当前串号
/// </summary>
/// <returns></returns>
public virtual int GetCurrent()
{
this._VisitorCounter++;
AppLocker.WaitOne();
try
{
CurrentNumber++;
return CurrentNumber;
}
finally
{
AppLocker.ReleaseMutex();
this._VisitorCounter--;
}
}
#endregion
#region public virtual void Reset()
/// <summary>
/// 重置当前串号为0,并更新统计日期
/// </summary>
public virtual void Reset()
{
this._VisitorCounter++;
AppLocker.WaitOne();
try
{
CurrentNumber = 0;
XmlDocument xd = new XmlDocument();
xd.Load(xmlPath);
XmlNode xn = xd.SelectSingleNode("/document/numberseed/date");
if (xn != null)
xn.InnerText = DateTime.Now.Date.ToString("yyyy-MM-dd");
xd.Save(xmlPath);
}
finally
{
AppLocker.ReleaseMutex();
this._VisitorCounter--;
}
}
#endregion
}
public class Global : System.Web.HttpApplication
{
/// <summary>
/// 稿件编号控制器
/// </summary>
Timer NumberControler;
/// <summary>
/// 控制器同步句柄
/// </summary>
AutoResetEvent NumberContorlerHandle = new AutoResetEvent(false);
protected void Application_Start(object sender, EventArgs e)
{
DateTime nextDayStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.AddDays(1).Day, 0, 0, 0);
//当前与下一天开始时间的时间差
TimeSpan diff = nextDayStart - DateTime.Now;
TimerCallback tc = new TimerCallback(ResetNumberCount);
NumberControler = new Timer(tc, NumberContorlerHandle, diff, new TimeSpan(24, 0, 0));
}
/// <summary>
/// 初始化稿件编号
/// </summary>
/// <param name="o"></param>
protected void ResetNumberCount(object o)
{
AutoResetEvent are = (AutoResetEvent)o;
NumberProviderFactory.GetNumberProvider(HttpRuntime.AppDomainAppPath + "documentconf.xml").Reset();
are.Set();
}
}