我目前使用Visual Studio在C#中创建应用程序。我想创建一些代码,以便当变量的值为1时执行某段代码。 我知道我可以使用if语句,但问题是值会在异步过程中更改,因此技术上if语句可能在值更改之前被忽略。如何在变量值更改时触发事件?
是否有可能创建一个事件处理程序,以便在变量值更改时触发一个事件?如果是这样,我该怎么做?
我完全可能误解了if语句的工作原理!任何帮助将非常感激。
我目前使用Visual Studio在C#中创建应用程序。我想创建一些代码,以便当变量的值为1时执行某段代码。 我知道我可以使用if语句,但问题是值会在异步过程中更改,因此技术上if语句可能在值更改之前被忽略。如何在变量值更改时触发事件?
是否有可能创建一个事件处理程序,以便在变量值更改时触发一个事件?如果是这样,我该怎么做?
我完全可能误解了if语句的工作原理!任何帮助将非常感激。
对我来说就像你想创建一个属性。
public int MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
if (_myProperty == 1)
{
// DO SOMETHING HERE
}
}
}
这使您可以随时在属性值更改时运行一些代码。如果你愿意,你可以在这里举办一个活动。
只需使用一个属性
int _theVariable;
public int TheVariable{
get{return _theVariable;}
set{
_theVariable = value;
if (_theVariable == 1){
//Do stuff here.
}
}
}
可以使用属性setter提高每当一个字段的值是不会改变的事件。
您可以拥有自己的EventHandler委托,也可以使用着名的System.EventHandler委托。
通常有一种模式,这样的:
下面是一个例子
private int _age;
//#1
public event System.EventHandler AgeChanged;
//#2
protected virtual void OnAgeChanged()
{
if (AgeChanged != null) AgeChanged(this,EventArgs.Empty);
}
public int Age
{
get
{
return _age;
}
set
{
//#3
_age=value;
OnAgeChanged();
}
}
这种方法的好处是,你让那些希望从你的类继承,如果需要改变行为的任何其他类。
如果你想捕获一个不同线程中的事件,它必须注意不要改变另一个线程中定义的对象的状态,这会导致引发一个交叉线程异常。为避免这种情况,您可以在要更改其状态的对象上使用Invoke方法,以确保更改发生在事件引发的同一线程中,或者如果您正在处理Windows窗体可以使用BackgourndWorker在并行线程中做一些很好很容易的事情。
.NET框架实际上提供了一个接口,您可以使用该接口在属性发生更改时通知订户:System.ComponentModel.INotifyPropertyChanged。这个接口有一个事件PropertyChanged。它通常用于WPF绑定,但我发现它在业务层中用作标准化属性更改通知的一种方法。
就线程安全性而言,我会在setter中放置一个锁,以便您不会遇到任何竞争条件。
这里是我的代码的想法:):
public class MyClass : INotifyPropertyChanged
{
private object _lock;
public int MyProperty
{
get
{
return _myProperty;
}
set
{
lock(_lock)
{
//The property changed event will get fired whenever
//the value changes. The subscriber will do work if the value is
//1. This way you can keep your business logic outside of the setter
if(value != _myProperty)
{
_myProperty = value;
NotifyPropertyChanged("MyProperty");
}
}
}
}
private NotifyPropertyChanged(string propertyName)
{
//Raise PropertyChanged event
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class MySubscriber
{
private MyClass _myClass;
void PropertyChangedInMyClass(object sender, PropertyChangedEventArgs e)
{
switch(e.PropertyName)
{
case "MyProperty":
DoWorkOnMyProperty(_myClass.MyProperty);
break;
}
}
void DoWorkOnMyProperty(int newValue)
{
if(newValue == 1)
{
//DO WORK HERE
}
}
}
希望这是有益:)
+1为包含其他答案省略的锁。 – ctacke 2011-04-30 23:35:18
对象_lock有什么用处? – 2015-01-27 10:05:55
@LodeVlaeminck它可以防止在处理事件时更改属性的值。 – 2016-04-15 07:30:16
只是要清楚,观察变量的变化才有可能为您自己的变量(或者是已经IObservable/INotifyPropertyChanged /事件相关)。如果系统变量没有被设计为可观察的,你就无法观察系统变量的变化。 – 2014-07-11 09:39:47