私は、PCの利用可能なドライブ上のディレクトリ関連の変更を追跡し、その変更をsqlite DBに保存するアプリケーションを開発しています。下のコードのすべてが正常に正常に動作しています。しかし約100個のディレクトリとそのネストされたディレクトリを一緒にコピーしてテストしたところ、アプリケーションがフリーズされ、Windows OSのコピー処理がフリーズされました。FilewatcherはほとんどのPCリソースを消費しています
バルクファイルのコピー用のこのコードは、ほとんどのPCリソースを消費しているため、管理方法がわかりません。なぜ私はそれを最適化することができますか?代わりに "IncludeSubDirectories = False"を設定しますか?
class DirWatcher
{
private FileSystemWatcher dirWatcher = null;
public void StartCapture()
{
string[] drives = Environment.GetLogicalDrives();
foreach (string drive in drives)
{
DriveInfo driveInfo = new DriveInfo(drive);
if (driveInfo.DriveType == DriveType.Fixed)
{
//Director Watcher
dirWatcher = new FileSystemWatcher(drive);
dirWatcher.NotifyFilter = NotifyFilters.DirectoryName;
dirWatcher.Created += dirWatcher_Created;
dirWatcher.Deleted += dirWatcher_Created;
dirWatcher.Renamed += dirWatcher_Renamed;
dirWatcher.IncludeSubdirectories = true;
dirWatcher.EnableRaisingEvents = true;
}
}
}
void dirWatcher_Renamed(object sender, RenamedEventArgs e)
{
try
{
Task.Factory.StartNew(() =>
{
saveToDB("Folder",
e.ChangeType.ToString(),
e.FullPath,
Utility.UnixDTstamp(DateTime.Now).ToString(),
Environment.UserName);
});
}
finally
{
dirWatcher.Renamed -= dirWatcher_Renamed;
}
}
void dirWatcher_Created(object sender, FileSystemEventArgs e)
{
try
{
Task.Factory.StartNew(() =>
{
saveToDB("Folder",
e.ChangeType.ToString(),
e.FullPath,
Utility.UnixDTstamp(DateTime.Now).ToString(),
Environment.UserName);
});
}
finally
{
dirWatcher.Created -= dirWatcher_Created;
}
}
public void StopCapture()
{
dirWatcher.IncludeSubdirectories = false;
dirWatcher.EnableRaisingEvents = false;
dirWatcher.Dispose();
}
public void saveToDB(string DirOrFile, string action, string path, string time, string userName)
{
//SavetoDB code will be here.
}
}
}
あなたのコードは多くのFSWオブジェクトを作成しますが、最後に作成されたものだけを停止します。あなたは決して他のインスタンスを保存しません。 'StartCapture'を呼び出すたびに、同じドライブを監視するより多くのインスタンスを作成します –
別の問題は、各イベントに対して* new *タスクを開始することです。 10Kのイベントを受け取ったら、10Kのタスクを作成します。限られた並列度(デフォルトの1もOKです)でActionBlockを使用して、投稿したいものを受け入れてSQLiteに保存します。 DOP = 1の場合、SQLiteファイルへの同時書き込みアクセスを制御する必要はありません –
1)make this Singleton Classを使用して、より多くのオブジェクトインスタンスを作成しないようにする必要があります。 2)私のアプリケーションでは、 'StartCapture'を一度だけ呼びます。私はあなたが言ったようにActionBlockを試しています。 – Jef