在 C# 中实现 Singleton
Leave a Comment2009.12.23 12:51 by Felicia
我们需要只有一个实例的类,并且需要提供一个用于访问实例的全局访问点,还希望确保解决方案是线程安全的。
下面的实现仅允许一个线程在尚未创建 Singleton 实例的情况下进入关键区域(该区域由 lock 块标识)。
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
Error – Unable to find manifest signing certificate in the certificate store
Leave a Comment2009.12.10 18:02 by Felicia
I got this when I renamed my C# project then tried to publish it. To solve, I went to the “Signing” tab of the project properties and unchecked “Sign the ClickOnce manifests”.
Good luck!
C# Accurate Timer
Leave a Comment2009.10.12 10:59 by Felicia
C# 有三个标准定时器,分别是 System.Windows.Forms.Timer, System.Threading.Timer, System.Timers.Timer。
这三个Timer都不是很准确,无法进行精确到1毫秒的定时。经测试,这三种Timer的最小触发时间间隔是大约15毫秒。
因此我们必须寻找另外的方案。
Windows提供了用于多媒体的winmm.dll,可以满足高精度定时的要求。
下面是winmm.dll提供的API的C#包装。
{
//Lib API declarations
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
static extern uint timeSetEvent(uint uDelay, uint uResolution, TimerCallback lpTimeProc, UIntPtr dwUser, uint fuEvent);
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
static extern uint timeKillEvent(uint uTimerID);
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
static extern uint timeGetTime();
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
static extern uint timeBeginPeriod(uint uPeriod);
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
static extern uint timeEndPeriod(uint uPeriod);
//Timer type definitions
[Flags]
public enum fuEvent : uint
{
TIME_ONESHOT = 0, //Event occurs once, after uDelay milliseconds.
TIME_PERIODIC = 1,
TIME_CALLBACK_FUNCTION = 0x0000, /* callback is function */
//TIME_CALLBACK_EVENT_SET = 0x0010, /* callback is event - use SetEvent */
//TIME_CALLBACK_EVENT_PULSE = 0x0020 /* callback is event - use PulseEvent */
}
//Delegate definition for the API callback
delegate void TimerCallback(uint uTimerID, uint uMsg, UIntPtr dwUser, UIntPtr dw1, UIntPtr dw2);
//IDisposable code
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
Stop();
}
}
disposed = true;
}
~MMTimer()
{
Dispose(false);
}
/// <summary>
/// The current timer instance ID
/// </summary>
uint id = 0;
/// <summary>
/// The callback used by the the API
/// </summary>
TimerCallback thisCB;
/// <summary>
/// The timer elapsed event
/// </summary>
public event EventHandler Timer;
protected virtual void OnTimer(EventArgs e)
{
if (Timer != null)
Timer(this, e);
}
public MMTimer()
{
//Initialize the API callback
thisCB = CBFunc;
}
/// <summary>
/// Stop the current timer instance (if any)
/// </summary>
public void Stop()
{
lock (this)
{
if (id != 0)
{
timeKillEvent(id);
Console.WriteLine("MMTimer " + id.ToString() + " stopped");
id = 0;
}
}
}
/// <summary>
/// Start a timer instance
/// </summary>
/// <param name="ms">Timer interval in milliseconds</param>
/// <param name="repeat">If true sets a repetitive event, otherwise sets a one-shot</param>
public void Start(uint ms, bool repeat)
{
//Kill any existing timer
Stop();
//Set the timer type flags
fuEvent f = fuEvent.TIME_CALLBACK_FUNCTION | (repeat ? fuEvent.TIME_PERIODIC : fuEvent.TIME_ONESHOT);
lock (this)
{
id = timeSetEvent(ms, 0, thisCB, UIntPtr.Zero, (uint)f);
if (id == 0)
throw new Exception("timeSetEvent error");
Console.WriteLine("MMTimer " + id.ToString() + " started");
}
}
void CBFunc(uint uTimerID, uint uMsg, UIntPtr dwUser, UIntPtr dw1, UIntPtr dw2)
{
//Callback from the MMTimer API that fires the Timer event. Note we are in a different thread here
OnTimer(new EventArgs());
}
}
转到计科的第一学期结束了
Leave a Comment2008.07.01 21:28 by Felicia
今年做的最大的决定,就是转专业到计科了。我在转专业之前考虑了很久,最终确定我的确比较适合学习计算机,之后就毫不犹豫的转了。因为是大二下转专业,所以我要补修非常多的课。其实这个学期还好,也就比同班的人多上了大学语文,数字逻辑,c语言。不过由于这个学期比赛比较多,final回来之后又陆续参加了一些小的比赛,所以平时的课有的没有办法上了。期末的时候学习非常紧张,考试频繁,很多东西我又是第一次接触。比如我先学微机系统与接口技术,再学数字逻辑,再学汇编语言,完全是跟正常的专业培养方案反过来了。还好我发现自己对计算机专业的知识有较强的领悟能力,一切都还能掌握。期末考试之前我采用两天复习法,每天复习两小时,基本上搞定所有的课。就等出成绩啦,嘿嘿!
[Read more]
