关于System.Timers.Timer的困惑

问题描述:

在正常情况下,不应该可以访问在TimerCallback函数的主线程上分配的属性值,对吧?关于System.Timers.Timer的困惑

我有一个使用一个计时器的类,这个类有TimerCallback的方法,好了,我访问该方法属性,如果没有多线程(我看到分配给主线程的值)

如果必要时我会粘贴一些代码,但我想知道如果我对定时器有一个主要困惑。

感谢

+0

属性是什么?一个WinForms表单? – Cameron

+0

不,对不起,这是一个windows服务上的商务课 – *er

它should't可以访问到指定的主线程上TimerCallback功能属性的值,对不对?

错!这仅仅是在你使用依赖主线程的UI的时候,例如使用winforms UI和WPF时的例子,甚至一些COM组件,你只能从它们在上创建的线程访问其成员,无论它是在哪里主线程与否。

但是,对于您构建的自定义类,哪个线程访问该成员并不重要,就是说,任何线程都可以访问该类及其成员,无论它在创建该类的线程上的哪个位置。

除了创建它们的线程(通常是主线程)之外,您不应该访问UI对象。如果你这样做,它可能可能工作,但你冒着抛出异常的风险,或更糟糕的是,事情默默地打破。

任何线程可以随时访问其他对象,不会抛出任何异常;但是您仍然必须小心避免并发情况。举例来说,如果你有这样的代码来创建一个单:

class Unique { 
    private static Unique instance; 

    public static Unique Instance { 
     get { 
      if (instance == null) { 
       instance = new Unique(); 
      } 

      return instance; 
     } 
    } 
} 

那么,如果两个线程同时访问Instance财产,他们可以最终创造了单的一个新实例(因为他们可以同时输入if)。

之一,以避免这些情况的最简单的方法是锁定:

lock (AnyObject) { 
    // Any other code locking on the same object cannot run while this code runs 
} 
+0

*哦,我的眼睛!*我不喜欢单身模式,即使它在http://csharpindepth.com/Articles详细解释过。 /General/Singleton.aspx :-) – Patrick

+0

@帕特里克:: PI只是用它作为你可以在线程中遇到的麻烦的简单例子 – Cameron

从文档System.Timers.Timer

如果使用定时器与用户界面元素,如窗体或控制,而无需在该用户界面元素上放置计时器,将包含Timer的表单或控件分配给SynchronizingObject属性,以便将事件编组到用户界面线程。