【发布时间】:2012-10-08 12:50:29
【问题描述】:
您好,我正在尝试在我的主线程上触发 Timer.Timer 类的 Elapsed 事件。 我仅限于 VS 2008,.net 3.5 ...... 在这篇文章中: Do C# Timers elapse on a separate thread? 据说使用 SynchronizingObject 将使处理程序在拥有该对象的线程上执行。
所以我尝试了这个:
class MyTimer
{
private readonly Timer timer;
public MyTimer(ISynchronizeInvoke synchronizingObject)
{
Console.Out.WriteLine(Thread.CurrentThread.ManagedThreadId);
timer = new Timer(1000);
timer.SynchronizingObject = synchronizingObject;
timer.Elapsed +=
delegate
{
timer.Stop();
Thread.Sleep(2000);
Console.Out.WriteLine(Thread.CurrentThread.ManagedThreadId);
timer.Start();
};
timer.Start();
}
}
class Program
{
static void Main(string[] args)
{
ISynchronizeInvoke syncObject = new Control();
var mytimer = new MyTimer(syncObject);
Console.ReadKey();
}
}
但是输出是:1,4,4,4,4...
这是为什么呢?如何让 Elapsed 处理程序在主线程上执行。
我尝试使用SynchronizingObject for an event 但这也无济于事:
public static ElapsedEventHandler Wrap(ElapsedEventHandler original, ISynchronizeInvoke synchronizingObject)
{
return (sender, args) =>
{
if (synchronizingObject.InvokeRequired)
{
synchronizingObject.Invoke(original, new object[] { sender, args });
}
else
{
original(sender, args);
}
};
}
和:
timer.Elapsed += Wrap(
delegate
{
timer.Stop();
Thread.Sleep(200);
Console.Out.WriteLine(Thread.CurrentThread.ManagedThreadId);
timer.Start();
},
synchronizingObject);
但仍然没有成功...每次 InvokeRequired 为假...
在调用中强制调试会导致无效操作:“在创建窗口句柄之前,不能对控件调用 Invoke 或 BeginInvoke。”
最后的手段是调查: http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class?msg=3655119#xx3655119xx 但这真的有必要吗?还是有一些更简单的解决方案?
【问题讨论】:
标签: c# .net multithreading timer deadlock