0

我在我想从其他类订阅的类中创建了一个静态事件。

public class PlaylistModel 
{
    public static event EventHandler PlaylistLoadError;
    public static void LoadPlaylist() 
    {
        try 
        {    
           // ...do some stuff...
        } 
        catch(SomeException ex) 
        {
            EventHandler handler = PlaylistLoadError;

            if(handler != null) 
            {
                PlaylistLoadError(null, null);
            }
        }
    }
}

在我的另一堂课上......

public partial class MainPage : PhoneApplicationPage 
{
    public MainPage() 
    {
        PlaylistModel.PlaylistLoadError += PlaylistError;
    }

    public void PlaylistError(object sender, EventArgs args) 
    {
        //... show the error ...
    }
}

在 catch 内部,handler 为 null,尽管它已被订阅。我MainPage在 catch 执行后从内部调试了程序,并且PlaylistLoadError显示为不为空。任何想法为什么它会在内部为空PlaylistModel,但在其他任何地方都没有?我有一种感觉,这与它是静态的有关。

4

2 回答 2

1

如果没有人订阅,则字段的值event可以为 null。从您的评论来看,您的 PlaylistModel 类中的异常似乎是在构造类之前引发的MainPage,此时尚未有人订阅该事件。

另请注意,这是内存泄漏的秘诀。当您的MainPage类(或任何其他类)订阅该事件时,Playlist该类持有对它的引用,并且Playlist该类中的事件是静态的。因此,所有订阅该事件的成员都将在您的应用程序的整个生命周期中存在。

于 2013-01-21T23:26:51.743 回答
0

事件委托的值在您将其分配给变量时被复制,但在您引发它时可能为空:

EventHandler handler = PlaylistLoadError;

if(handler != null) { // not null
    PlaylistLoadError(null, null); // null
}

您可以通过执行局部变量而不是从事件中重新获取委托来避免错误:

EventHandler handler = PlaylistLoadError;

if(handler != null) {
    handler(this, EventArgs.Empty);
}

this并且EventArgs.Empty也是更好的默认值null

于 2013-01-22T00:39:23.790 回答