3

特定のディレクトリに新しい/既存のファイルが見つかった/作成された場合に発生するカスタム イベントが必要です。新しいファイルが作成されたかどうかを確認するには、正常に動作する 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-Event が OnNewFileDetect-Event を発生させた場合、すべて正常に動作することです。しかし、checkExistingFiles がいくつかの既存のファイルを見つけ、OnNewFileDetect-Event を発生させようとしても、何も起こりません。OnNewFileDetectEvent-Object が null であるため、何も起こらないことがわかりました。しかし、onFileCreated-Event が発生した場合、なぜ null ではないのでしょうか?

4

2 に答える 2

2

しかし、onFileCreated-Event が発生した場合、なぜ 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);
    }
}
于 2012-04-10T23:43:17.363 に答える
1

@Reed Copsey が質問に答えました。イベントはnullサブスクライバーがいるまで続きます。

また、これは潜在的な競合状態です。

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

マルチスレッドのシナリオでは、ステートメントの後、次の行の呼び出しの前にOnNewFileDetectEventが設定されている場合、プログラムがクラッシュすることに注意してください。通常、次のようにします。nullif

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

イベントオブジェクトは不変であるため、ステートメントdelでnullでない場合、nullになることはありません。if

また、あなたの命名は型にはまらないことに注意してください。通常、イベントにはプレフィックス は付けられませんOn。イベントを呼び出すメソッドは です。

于 2012-04-10T23:52:59.627 に答える