C# 如何正确引发自定义事件?

C# 如何正确引发自定义事件?,c#,events,C#,Events,我需要一个自定义事件,如果在特定目录中找到/创建了新的/现有的文件,则该事件将引发。为了检查是否创建了新文件,我使用SystemFileWatcher,它工作正常。为了检查程序开始时是否存在一些文件,我写了几行代码,这对 我将此类用于事件参数: public class FileDetectEventArgs : EventArgs { public String Source { get; set; } public String Destination { get; set;

我需要一个自定义事件,如果在特定目录中找到/创建了新的/现有的文件,则该事件将引发。为了检查是否创建了新文件,我使用SystemFileWatcher,它工作正常。为了检查程序开始时是否存在一些文件,我写了几行代码,这对

我将此类用于事件参数:

public class FileDetectEventArgs : EventArgs
{
    public String Source { get; set; }
    public String Destination { get; set; }
    public String FullName { get; set; }

    public FileDetectEventArgs(String source, String destination, String fullName)
    {
        this.Source = source;
        this.Destination = destination;
        this.FullName = fullName;
    }
}
如果SystemFileWatcher引发FileCreated事件,我将使用以下代码行:

public void onFileCreated(object sender, FileSystemEventArgs e)
{
    // check if file exist
    if (File.Exists(e.FullPath))
    {
        OnNewFileDetect(new FileDetectEventArgs(source, destination, e.FullPath));  
    }
}
如果存在文件,我会尝试以这种方式引发事件:

public void checkExistingFiles(String source, String filter)
    {
        DirectoryInfo di = new DirectoryInfo(source);
        FileInfo[] fileInfos = di.GetFiles();
        String fileFilter = filter.Substring(filter.LastIndexOf('.'));       

        foreach (FileInfo fi in fileInfos)
        {
            if (fi.Extension.Equals(fileFilter))
            {
                OnNewFileDetect(new FileDetectEventArgs(source, destination, fi.FullName));                   
            }
        }
    }
以下是OnNewFileDetect事件:

protected void OnNewFileDetect(FileDetectEventArgs e)
    {
        if (OnNewFileDetectEvent != null)
        {
            OnNewFileDetectEvent(this, e);
        }
    }
问题是,如果onFileCreated事件引发我的OnNewFileDetect事件,所有这些都可以正常工作。但是如果checkExistingFiles发现一些现有文件并尝试引发OnNewFileDetect事件,则不会发生任何事情。我发现onnewFileDetecteEvent对象为null,因此不会发生任何事情。但是,如果触发onFileCreated事件,为什么它不为null呢

但是,如果onFileCreated事件被激发,为什么它不为null呢

此事件将为null,直到有人订阅该事件


在一个旁注下,我会考虑切换到一个更好的模式来提高事件,以及在这里使用标准的C./.NET命名。这更像是:

// The event...
public EventHandler<FileDetectedEventArgs> NewFileDetected;

// Note the naming
protected void OnNewFileDetected(FileDetectedEventArgs e)
{
    // Note this pattern for thread safety...
    EventHandler<FileDetectedEventArgs> handler = this.NewFileDetected; 
    if (handler != null)
    {
        handler(this, e);
    }
}
//事件。。。
检测到公共事件处理程序newfilehandler;
//注意命名
已检测到受保护的无效文件(FileDetectedEventArgs e)
{
//请注意此模式以确保线程安全。。。
EventHandler=this.NewFileDetected;
if(处理程序!=null)
{
处理者(本,e);
}
}

@Reed Copsey回答了这个问题;在拥有订户之前,事件将为
null

此外,这是一种潜在的竞争条件:

if (OnNewFileDetectEvent != null)
{
    OnNewFileDetectEvent(this, e);
}
请注意,在多线程场景中,如果在
if
语句之后,但在下一行调用之前,将
onnewFileDetecteEvent
设置为
null
,则程序将崩溃。通常,您会这样做:

var del = OnNewFileDetectEvent;
if (del != null)
{
    del(this, e);
}
由于事件对象是不可变的,
del
如果在
if
语句中不为null,它将永远不会为null


还要注意,您的命名是非传统的。事件的前缀通常不是
On
,调用事件的方法是。

谢谢您的快速回答。现在我得到了错误:委托“FileDetectedEvent”不接受两个arguments@thomas如何声明事件?公共委托void filedetectedevent(对象发送方,FileDetectedEventArgs e)@Reed CopseyOk也谢谢你,但是为什么我现在得到错误:委托“FileDetectedEvent”不接受两个参数