thomas
thomas

Reputation: 164

How to raise custom event correctly?

I need a custom event that should raise if a new/existing file in a specific directory was found/created. To check if a new File was created I use the SystemFileWatcher, which works fine. To check if some files exist at program start I wrote some lines and that works to.

I use this class for event args:

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;
    }
}

If the SystemFileWatcher raise a FileCreated Event I use these lines of code:

public void onFileCreated(object sender, FileSystemEventArgs e)
{
    // check if file exist
    if (File.Exists(e.FullPath))
    {
        OnNewFileDetect(new FileDetectEventArgs(source, destination, e.FullPath));  
    }
}

And if a file exist I try to raise the event in that way:

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));                   
            }
        }
    }

Here is the OnNewFileDetect-Event:

protected void OnNewFileDetect(FileDetectEventArgs e)
    {
        if (OnNewFileDetectEvent != null)
        {
            OnNewFileDetectEvent(this, e);
        }
    }

The problem is, if the onFileCreated-Event raises my OnNewFileDetect-Event all works fine. But if the checkExistingFiles found some existing files and try to raise OnNewFileDetect-Event nothing happen. I found out that the OnNewFileDetectEvent-Object is null and so nothing happen. But why it's not null if the onFileCreated-Event is fired?

Upvotes: 3

Views: 1367

Answers (2)

Ed Swangren
Ed Swangren

Reputation: 124790

@Reed Copsey answered the question; the event will be null until it has a subscriber.

Also, this is a potential race condition:

if (OnNewFileDetectEvent != null)
{
    OnNewFileDetectEvent(this, e);
}

Note that, in a multi-threaded scenario, if OnNewFileDetectEvent is set to null after the if statement, but before the invocation on the next line, your program will crash. Generally you would do this:

var del = OnNewFileDetectEvent;
if (del != null)
{
    del(this, e);
}

As your event object is immutable del will never be null if it is not null in the if statement.

Also note that your naming is unconventional. An event is not typically prefixed with On, the method that invokes the event is.

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564921

But why its not null if the onFileCreated-Event is fired?

This event will be null until something subscribes to the event.


On a side note, I'd consider switching to a better pattern for raising the event, as well as using standard C#/.NET naming here. This would be more like:

// 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);
    }
}

Upvotes: 2

Related Questions