相关疑难解决方法(0)

检查委托是否为null

我正在阅读Essential C#3.0书籍,我想知道这是否是检查代表为空的好方法?:

class Thermostat
{
    public delegate void TemperatureChangeHandler ( float newTemperature );

    public TemperatureChangeHandler OnTemperatureChange { get; set; }

    float currentTemperature;

    public float CurrentTemperature
    {
        get { return this.currentTemperature; }
        set
        {
            if ( currentTemperature != value )
            {
                currentTemperature = value;

                TemperatureChangeHandler handler = OnTemperatureChange;

                if ( handler != null )
                {
                    handler ( value );
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果类型是不可变的,解决方案是否会更改?我认为可能具有不变性,你不会遇到这个线程问题.

.net c# delegates

11
推荐指数
3
解决办法
3万
查看次数

C#提升事件

我最近一直在使用C#工作,我注意到在我公司的代码中引发事件的大多数代码都是这样完成的:

EventHandler handler = Initialized;

if (handler != null)
{
    handler(this, new EventArgs());
}
Run Code Online (Sandbox Code Playgroud)

我真的不明白为什么相反,你不能这样做:

if (Initialized != null)
{
    Initialized(this, new EventArgs());
}
Run Code Online (Sandbox Code Playgroud)

编辑:

有些值得深思,我试着对此做一些测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test t = new Test(true);

            while(true)
            {
                t.Ev += new EventHandler(t_Ev);
                t.Ev -= new EventHandler(t_Ev);
            }
        }

        static void t_Ev(object sender, EventArgs e)
        {
        }
    }

    public class Test
    {
        private readonly bool …
Run Code Online (Sandbox Code Playgroud)

c# events

8
推荐指数
1
解决办法
1254
查看次数

如果C#事件处理程序处理并且我调用它会发生什么?

这个问题是对C#事件和线程安全问题的跟进(我不是那个问题的作者)和Eric Lippert Events and Races的相关博客文章.关于SO还有其他类似的问题,但他们都没有真正考虑过这个案例,普遍的共识是只要你取消订阅就是安全的,但我不相信这一直是真的.

根据SO问题和博客中的讨论,应该使用的模式类似于:

var ev = NotifyPropertyChanged;
if (ev != null)
    ev(this, new PropertyChangedEventArgs("Foo"));
Run Code Online (Sandbox Code Playgroud)

但是如果出现以下情况怎么办:
1)我订阅了一个监听器:

mytype.NotifyPropertyChanged += Handler; // Handler is instance method in SomeObject class
Run Code Online (Sandbox Code Playgroud)

2)I(或运行时,由于作用域)在几乎同时发生属性通知的同时处理SomeObject,它包含监听器并取消订阅监听器.

3)虽然由于非常短的时间段可能发生这种情况,但理论上可能因为ev保留了不再存在的旧订户,它将在不再存在的对象中调用函数.

根据Eric Lippert的说法," 即使在事件被取消订阅之后,事件处理程序也必须是强大的." 但是如果处理程序被取消订阅并处理掉,它就不能再处理这个电话了.处理这种情况的正确方法是什么?

在try-catch中包装(1)中的代码?应该抓住什么例外?我认为ObjectDisposedException似乎很可能,但不是唯一可能发生的事件.

.net c# events thread-safety

7
推荐指数
1
解决办法
1741
查看次数

如何在VB.NET中引发事件之前检查订阅者

在C#中,你做这样的事情:

if (Changed != null)
    Changed(this, EventArgs.Empty);
Run Code Online (Sandbox Code Playgroud)

但是你在VB.NET中做了什么?

RaiseEvent,但是

RaiseEvent Changed(Me, EventArgs.Empty)
Run Code Online (Sandbox Code Playgroud)

实际上检查某事已订阅该事件?

.net vb.net event-handling raiseevent

7
推荐指数
1
解决办法
3250
查看次数

Extension方法线程安全吗?

这个Extension方法线程安全吗?

   public static class Extensions
   {
      public static void Raise<T>(this EventHandler<T> handler,
        object sender, T args) where T : EventArgs
      {
         if (handler != null) handler(sender, args);
      }
   }
Run Code Online (Sandbox Code Playgroud)

或者我需要将其改为此吗?

   public static class Extensions
   {
      public static void Raise<T>(this EventHandler<T> handler,
        object sender, T args) where T : EventArgs
      {
         var h = handler;
         if (h!= null) h(sender, args);
      }
   }
Run Code Online (Sandbox Code Playgroud)

c# extension-methods thread-safety

6
推荐指数
2
解决办法
2886
查看次数

EventHandler:这段代码发生了什么?

这段代码为名为的事件添加了新的EventHandler寄存器NewMail(eventargs类被命名NewMailEventArgs.

// A PUBLIC add_xxx method (xxx is the event name)
// Allows methods to register interest in the event.
public void add_NewMail(EventHandler<NewMailEventArgs> value) {
  // The loop and the call to CompareExchange is all just a fancy way
  // of adding a delegate to the event in a thread-safe way.
  EventHandler<NewMailEventArgs> prevHandler;
  EventHandler<NewMailEventArgs> newMail = this.NewMail;
  do {
     prevHandler = newMail;
     EventHandler<NewMailEventArgs> newHandler = (EventHandler<NewMailEventArgs>)Delegate.Combine(prevHandler, value);
     newMail = Interlocked.CompareExchange<EventHandler<NewMailEventArgs>>(ref this.NewMail, newHandler, prevHandler);
    }
  while(newMail != …
Run Code Online (Sandbox Code Playgroud)

c# events delegates event-handling

5
推荐指数
1
解决办法
369
查看次数

INotifyProperyChanged - 为什么额外的任务?

INotifyPropertyChanged以最基本的形式实现接口时,大多数人似乎都像这样实现它::

public virtual void OnPropertyChanged(string propertyName)
{
    var propertyChanged = PropertyChanged;
    if (propertyChanged != null)
    {
        propertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么要额外分配var propertyChanged = PropertyChanged;?这只是一个偏好的问题,还是有充分的理由呢?当然以下是有效的吗?

public virtual void OnPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
Run Code Online (Sandbox Code Playgroud)

.net c# inotifypropertychanged

5
推荐指数
1
解决办法
218
查看次数

Initializeng事件与检查null

基本上这已经在我的脑海里了一段时间......我想读你的意见

我从Jon Skeet那里读到了一本伟大的书:C#in Depth,Second Edition,并建议在声明自定义事件时使用类似的东西:

public event Action<string> MyEvent = delegate { };
Run Code Online (Sandbox Code Playgroud)

此声明将在触发事件之前将我们从nullity check语句中释放出来,因此不是这样:

    if (this.MyEvent != null)
    {
        this.MyEvent("OMG osh");
    }
Run Code Online (Sandbox Code Playgroud)

我们可以简单地致电:

this.MyEvent("OMG osh");
Run Code Online (Sandbox Code Playgroud)

我们的代码只会起作用.

当您声明这样的事件时,将使用空委托初始化事件,因此我们不需要检查null.

这是声明事件的另一种方式,它们是等价的

private Action<string> myDelegate;
public event Action<string> MyEvent
{
    add
    {
        this.myDelegate += value;
    }
    remove
    {
        this.myDelegate -= value;
    }
}
Run Code Online (Sandbox Code Playgroud)

欲了解更多信息:http://csharpindepth.com/Articles/Chapter2/Events.aspx

我刚刚与一些研究员进行了讨论,在工作中我们正在讨论这个主题,他们争辩说有时候我们需要立即清除事件的所有订阅,我们可以简单地为后面的委托指定null如果我们想继续使用相同的模式,我们将不得不用空委托重新初始化事件.他们还询问在多线程场景中会发生什么,这是我提出这个问题的主要原因

  1. 我想知道在声明此模式后的事件与检查null时是否存在一些隐藏的含义(可能在使用多线程时)

  2. 如果我使用这个模式,我实际上删除了几个if条件,这导致删除跳转语句.这在整体性能方面不会更好吗?

干杯

c#

5
推荐指数
1
解决办法
717
查看次数

为什么在实现iNotifyPropertyChanged时检查PropertyChanged事件的空值?

我正在详细阅读iNotifyPropertyChanged.

有人可以澄清为什么我们需要检查 PropertyChanged !=null

为什么一个事件是空的?或者换句话说,为什么甚至检查它是否为空?NotifyPropertyChanged调用的唯一时间是何时PropertyChanged被引发(因此它不能为null),不是它.谁/什么可以使它为空?

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this,new PropertyChangedEventArgs(info));
        }

    }
Run Code Online (Sandbox Code Playgroud)

谢谢.

c# mvvm

5
推荐指数
1
解决办法
1453
查看次数

在调用之前将EventHandler分配给局部变量

我注意到很多代码使用以下代码片段来调用事件处理程序.

Public event EventHandler Handler;

Protected void OnEvent(){
      var handler = this.Handler;
      If(null!=handler){
          handler(this, new EventArgs());
      }
}
Run Code Online (Sandbox Code Playgroud)

为什么Handler在调用之前将其分配给局部变量而不是Handler直接调用事件.那些之间有什么区别吗?

c#

5
推荐指数
1
解决办法
750
查看次数