源代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass();
t.Start();
Thread.Sleep(30000);
t.Dispose();
Thread.Sleep(30000);
}
} public class TestClass : IDisposable
{
private Timer _timer; public void Start()
{
_timer = new Timer(new TimerCallback(JobCallBack), null, 1000, 1000);
} private void JobCallBack(object state)
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
Console.WriteLine("Starting...");
Thread.Sleep(10000);
Console.WriteLine("Complete");
_timer.Change(1000, 1000);
} public void Dispose()
{
if (_timer != null)
{
_timer.Dispose();
_timer = null;
}
Console.WriteLine("Disposed");
}
}
}
以上代码输出结果为:
Starting...
Complete
Starting...
Complete
Starting...
Disposed
Complete未处理的异常: System.NullReferenceException: 未将对象引用设置到对象的实例。
在 ConsoleApplication1.TestClass.JobCallBack(Object state) 位置 C:\ConsoleA
pplication1\Program.cs:行号 35
在 System.Threading._TimerCallback.TimerCallback_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
ontextCallback callback, Object state)
在 System.Threading._TimerCallback.PerformTimerCallback(Object state)------------------------------------------
开始程序是正常运行的,但调用Dispose后程序发生异常,经过我分析,发现问题如下:
主程序方法 Main 中调用了Dispose,因此,TestClass 中的 _timer 为null了,而此时TestClass中的JobCallBack方法尚未结束,因此调用_timer.Change自然会出错了。请问这该如何解决呢?谢谢大家了!
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass();
t.Start();
Thread.Sleep(30000);
t.Dispose();
Thread.Sleep(30000);
}
} public class TestClass : IDisposable
{
private Timer _timer; public void Start()
{
_timer = new Timer(new TimerCallback(JobCallBack), null, 1000, 1000);
} private void JobCallBack(object state)
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
Console.WriteLine("Starting...");
Thread.Sleep(10000);
Console.WriteLine("Complete");
_timer.Change(1000, 1000);
} public void Dispose()
{
if (_timer != null)
{
_timer.Dispose();
_timer = null;
}
Console.WriteLine("Disposed");
}
}
}
以上代码输出结果为:
Starting...
Complete
Starting...
Complete
Starting...
Disposed
Complete未处理的异常: System.NullReferenceException: 未将对象引用设置到对象的实例。
在 ConsoleApplication1.TestClass.JobCallBack(Object state) 位置 C:\ConsoleA
pplication1\Program.cs:行号 35
在 System.Threading._TimerCallback.TimerCallback_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, C
ontextCallback callback, Object state)
在 System.Threading._TimerCallback.PerformTimerCallback(Object state)------------------------------------------
开始程序是正常运行的,但调用Dispose后程序发生异常,经过我分析,发现问题如下:
主程序方法 Main 中调用了Dispose,因此,TestClass 中的 _timer 为null了,而此时TestClass中的JobCallBack方法尚未结束,因此调用_timer.Change自然会出错了。请问这该如何解决呢?谢谢大家了!
解决方案 »
- c#开发插件系统时,插件如何调用宿主的相关内容
- Winform中如何自定义卸载程序
- SQL数据库事务批量添加中禁止重复值的问题
- C#连接oracle中文显示乱码,求高手解决
- scoket通讯!!!帮忙看下,谢谢了
- VS2005 Team Suit 简体中文版的Asp.Net web项目不能生成release版本?
- listview获得指定索引处的各栏内容
- 消息队列 长度不能小于 0。 参数名: length
- 大家好!
- 渴望答案:一个.NET与数据库连接操作的问题!!!
- 请问在VS2003 ,在Windows Form程序中,DataGrid控件中怎么实现超过规定记录数目就自动分页的功能?谢谢
- 不使用析构函数的话,在类中如何知道 实例已经退出可以释放资源(比如断开数据库)和保存缓存的数据了?
另外,关于你说的“如果不想再运行Timer了,最好在callback中,不要再用change来进行修改。”
就拿我的那个callback函数来说吧,代码如下:
private void JobCallBack(object state)
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
Console.WriteLine("Starting...");
Thread.Sleep(10000);
Console.WriteLine("Complete");
_timer.Change(1000, 1000);
}
我的这个callback函数中,用change来修改只是想临时禁止Timer,目的是防止这次调用还没完成,下次调用又来了,但是在我的callback完成后我还是需要继续Timer的。
这个我看CS和Forum2,还有其它一些例子也是这么用的,难道这样用不妥吗?请指点,如果不好的话,那这个该如何弄呢?谢谢!
他是在Timer的callback方法中自己判断并结束Timer,这个与我的不一样的。我是要外面控制Timer的结束。正因为我是在外面控制(调用Dispose方法),所以才会出现设置Timer为NULL的时候,而callback还在运行的情况,这就出现了异常。
首先你需要用类的成员保存TimerExampleState,然后在CallBack函数中判断state,或者可以用一个成员来标示要进行dispose操作,
那么在类的Dispose中,先告诉当前状态,然后判断TimerExampleState对象是否已经关闭,然后带调用Timer的dispose。
public class TestClass : IDisposable
{
private Timer _timer;
private bool blnDisposed = false; public void Start()
{
_timer = new Timer(new TimerCallback(JobCallBack), null, 1000, 1000);
} private void JobCallBack(object state)
{
_timer.Change(Timeout.Infinite, Timeout.Infinite);
Debug.WriteLine("Starting...");
Thread.Sleep(10000);
Debug.WriteLine("Complete");
if( !blnDisposed )
_timer.Change(1000, 1000);
else
_timer = null;
} public void Dispose()
{
if (_timer != null)
{
blnDisposed = true;
while(_timer != null)
Thread.Sleep(5);
}
Debug.WriteLine("Disposed");
}
}
public void Dispose()
{
if (_timer != null)
{
lock(this)
{
blnDisposed = true;
while(_timer != null)
Thread.Sleep(5);
}
}
我觉得这里加lock没有任何必要吧?你觉得呢?谢谢!