![](/img/trans.png)
[英]How do you access an attached property of a Silverlight object in C#?
[英]How do I get access to the object which the Timer is attached to?
我有一個編程問題,我認為這是由於我在使用事件和委托時的生銹而引起的...
我有代碼:
public void DoStuff()
{
List<IProcess> processorsForService1 = processorsForService1 = ProcessFactory.GetProcessors();
foreach (IProcess p in processorsForService1)
{
if (p.ProcessTimer != null)
{
p.ProcessTimer.Elapsed += new ElapsedEventHandler(IProcess_Timer_Elapsed);
}
}
}
和:
private void IProcess_Timer_Elapsed(object sender, ElapsedEventArgs e)
{
IProcess p = (IProcess)sender;
p.Step_One();
p.Step_Two();
}
但是,當我到達事件處理程序時,我在第一行獲取p的空引用異常。
在這種情況下,如何將參數傳遞給處理程序?
看起來您正在使用System.Timers.Timer
,如果要使用System.Threading.Timer
則可以傳遞一個state
對象,在這種情況下,該對象可能是所需的類實例,即計時器的'所有者'。 這樣,您就可以定義方法主體,就像您以前在事件處理程序中實現的經驗一樣,只是現在簽名如下:
private void MyTimerCallbackMethod(object state)
{
}
然后,在創建計時器實例后,您可以執行以下操作:
var timerCallback = new TimerCallback(MyTimerCallback);
var timer = new Timer(timerCallback, myStateObject,
Timeout.Infinite, Timeout.Infinite);
然后,使用timer.Change(whenToStart, interval)
啟動計時器。
發送者是計時器對象,而不是與處理委托關聯的對象。 首先,事件可以具有多個處理程序。
您可以做的是創建一個可以使用變量捕獲訪問IProcess
的委托。
如果使用lambda而不是委托,則可以從lambda引用該類,因為它仍在引用環境中。 我認為這稱為Closure 。
public void DoStuff()
{
List<IProcess> processorsForService1 = ProcessFactory.GetProcessors();
foreach (IProcess p in processorsForService1)
{
if (p.ProcessTimer != null)
{
p.ProcessTimer.Elapsed += (s, e) =>
{
p.Step_One();
p.Step_Two();
};
}
}
}
但是請注意以下與范圍相關的規則(取自msdn ):
以下規則適用於lambda表達式中的變量范圍:
捕獲的變量將不會被垃圾回收,直到引用它的委托超出范圍。
在lambda表達式中引入的變量在外部方法中不可見。
Lambda表達式無法直接從封閉方法中捕獲ref或out參數。
lambda表達式中的return語句不會導致封閉方法返回。
Lambda表達式不能包含goto語句,break語句或Continue語句,其目標位於包含的匿名函數的主體之外或主體中。
使事件處理程序成為IProcess的成員,並按如下所示進行設置:
p.ProcessTimer.Elapsed += new ElapsedEventHandler(p.IProcess_Timer_Elapsed);
如果要在其他地方處理該事件,請使處理程序轉發該事件:
class IProcess
{
public delegate void Timer_Elapsed_Handler (IProcess process, ElapsedEventArgs e);
public event Timer_Elapsed_Handler Timer_Elapsed;
public void IProcess_Timer_Elapsed (object sender, ElapsedEventArgs e)
{
if (Timer_Elapsed != null) Timer_Elapsed (this, e);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.