嗨,我正在尝试在我的主线程上触发 Timer.Timer 类的 Elapsed 事件。我仅限于 VS 2008、.net 3.5... 在这篇文章中: C# 计时器是否在单独的线程上运行? 据说使用 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 用于事件 ,但这也无济于事:
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 但这真的有必要吗?还是有一些更简单的解决方案?