时间:2019-03-08 标签:c#filesystemwatcher and backgroundworker
c# filesystemwatcher and backgroundworker
我想要同步我的文件夹,所以我有 10 个 Filesystemwatcher 和 4 个 Backgroundworker。
这个想法是,一个观察者可以调用 4 个工作人员中的每一个,但我希望观察者选择一个活跃且空闲的工作人员,不应触发其他工作人员。
Exp: 工人 1 被解雇,2-4 没有。
我做错了什么?
这是我的代码
private void watcher1_OnChanged(object source, FileSystemEventArgs e)
{
// File Name
string file = e.FullPath;
// refresh App.Config
ConfigurationManager.RefreshSection("appSettings");
// Check Worker Active
bool worker1Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker1Active"]);
bool worker2Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker2Active"]);
bool worker3Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker3Active"]);
bool worker4Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker4Active"]);
// Watcher Nummer
string watcherNr = "Watcher 1";
// Arguments to call worker
List<object> arguments = new List<object>();
arguments.Add(file);
arguments.Add(watcher1_destinationPath);
arguments.Add(watcher1_sourcePath);
arguments.Add(watcherNr);
bool success = false;
while (!success == true)
{
try
{
using (Stream stream = new FileStream(file, FileMode.Open))
{
if (worker1Active == true && worker1.IsBusy != true)
{
worker1.RunWorkerAsync(arguments);
success = true;
break;
}
if (worker2Active == true && worker2.IsBusy != true)
{
worker2.RunWorkerAsync(arguments);
success = true;
break;
}
if (worker3Active == true && worker3.IsBusy != true)
{
worker3.RunWorkerAsync(arguments);
success = true;
break;
}
if (worker4Active == true && worker4.IsBusy != true)
{
worker4.RunWorkerAsync(arguments);
success = true;
break;
}
}
}
catch
{
success = false;
}
}
}
你应该使用线程池。这将使您的代码看起来更干净,这就是您应该使用的线程机制。它会将任务放在空闲线程之一上,如果所有线程都忙,那么它将等待其中一个线程空闲。
这里是关于如何在 c# 中使用线程池的link。
https://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx
https://www.dotnetperls.com/threadpool
此外,如果您想继续一次只使用四个线程,您可以设置最大数量。线程中的线程
Here is how to do it.
编辑: 确保在处理期间锁定文件并在处理前检查锁定。如果您有多个工作人员处理一个文件,您将 运行 遇到问题。只要确保在要处理的文件被锁定时重新排队作业即可。它会自动重新排队,直到解锁。当然你需要注意再次解锁。
这是一个使用线程池的示例应用:
ThreadPool 是线程安全的,这意味着当它工作时,它在不同的线程中进行,这将使您的 UI 保持响应而不是阻塞。
玩得开心!
using System;
using System.IO;
using System.Threading;
namespace FileWatcherThreadApp
{
class Program
{
static void Main(string[] args)
{
FileSystemWatcher fileWatcher = new FileSystemWatcher(@"C:\Users\BertSinnema\watch");
//Enable events
fileWatcher.EnableRaisingEvents = true;
//Add event watcher
fileWatcher.Changed += FileWatcher_Changed;
fileWatcher.Created += FileWatcher_Changed;
fileWatcher.Deleted += FileWatcher_Changed;
fileWatcher.Renamed += FileWatcher_Changed;
var maxThreads = 4;
// Times to as most machines have double the logic processers as cores
ThreadPool.SetMaxThreads(maxThreads, maxThreads * 2);
Console.WriteLine("Listening");
Console.ReadLine();
}
//This event adds the work to the Thread queue
private static void FileWatcher_Changed(object sender, FileSystemEventArgs e)
{
ThreadPool.QueueUserWorkItem((o) => ProcessFile(e));
}
//This method processes your file, you can do your sync here
private static void ProcessFile(FileSystemEventArgs e)
{
// Based on the eventtype you do your operation
switch (e.ChangeType)
{
case WatcherChangeTypes.Changed:
Console.WriteLine($"File is changed: {e.Name}");
break;
case WatcherChangeTypes.Created:
Console.WriteLine($"File is created: {e.Name}");
break;
case WatcherChangeTypes.Deleted:
Console.WriteLine($"File is deleted: {e.Name}");
break;
case WatcherChangeTypes.Renamed:
Console.WriteLine($"File is renamed: {e.Name}");
break;
}
}
}
}
如果您想查看多个文件夹,只需添加另一个 FileSystemWatcher 并将创建、重命名、更改和删除事件挂接到同一个事件处理程序 (FileWatcher_Changed)
我想要同步我的文件夹,所以我有 10 个 Filesystemwatcher 和 4 个 Backgroundworker。 这个想法是,一个观察者可以调用 4 个工作人员中的每一个,但我希望观察者选择一个活跃且空闲的工作人员,不应触发其他工作人员。
Exp: 工人 1 被解雇,2-4 没有。
我做错了什么?
这是我的代码
private void watcher1_OnChanged(object source, FileSystemEventArgs e)
{
// File Name
string file = e.FullPath;
// refresh App.Config
ConfigurationManager.RefreshSection("appSettings");
// Check Worker Active
bool worker1Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker1Active"]);
bool worker2Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker2Active"]);
bool worker3Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker3Active"]);
bool worker4Active = Convert.ToBoolean(ConfigurationManager.AppSettings["worker4Active"]);
// Watcher Nummer
string watcherNr = "Watcher 1";
// Arguments to call worker
List<object> arguments = new List<object>();
arguments.Add(file);
arguments.Add(watcher1_destinationPath);
arguments.Add(watcher1_sourcePath);
arguments.Add(watcherNr);
bool success = false;
while (!success == true)
{
try
{
using (Stream stream = new FileStream(file, FileMode.Open))
{
if (worker1Active == true && worker1.IsBusy != true)
{
worker1.RunWorkerAsync(arguments);
success = true;
break;
}
if (worker2Active == true && worker2.IsBusy != true)
{
worker2.RunWorkerAsync(arguments);
success = true;
break;
}
if (worker3Active == true && worker3.IsBusy != true)
{
worker3.RunWorkerAsync(arguments);
success = true;
break;
}
if (worker4Active == true && worker4.IsBusy != true)
{
worker4.RunWorkerAsync(arguments);
success = true;
break;
}
}
}
catch
{
success = false;
}
}
}
你应该使用线程池。这将使您的代码看起来更干净,这就是您应该使用的线程机制。它会将任务放在空闲线程之一上,如果所有线程都忙,那么它将等待其中一个线程空闲。
这里是关于如何在 c# 中使用线程池的link。
https://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx https://www.dotnetperls.com/threadpool
此外,如果您想继续一次只使用四个线程,您可以设置最大数量。线程中的线程 Here is how to do it.
编辑: 确保在处理期间锁定文件并在处理前检查锁定。如果您有多个工作人员处理一个文件,您将 运行 遇到问题。只要确保在要处理的文件被锁定时重新排队作业即可。它会自动重新排队,直到解锁。当然你需要注意再次解锁。
这是一个使用线程池的示例应用: ThreadPool 是线程安全的,这意味着当它工作时,它在不同的线程中进行,这将使您的 UI 保持响应而不是阻塞。
玩得开心!
using System;
using System.IO;
using System.Threading;
namespace FileWatcherThreadApp
{
class Program
{
static void Main(string[] args)
{
FileSystemWatcher fileWatcher = new FileSystemWatcher(@"C:\Users\BertSinnema\watch");
//Enable events
fileWatcher.EnableRaisingEvents = true;
//Add event watcher
fileWatcher.Changed += FileWatcher_Changed;
fileWatcher.Created += FileWatcher_Changed;
fileWatcher.Deleted += FileWatcher_Changed;
fileWatcher.Renamed += FileWatcher_Changed;
var maxThreads = 4;
// Times to as most machines have double the logic processers as cores
ThreadPool.SetMaxThreads(maxThreads, maxThreads * 2);
Console.WriteLine("Listening");
Console.ReadLine();
}
//This event adds the work to the Thread queue
private static void FileWatcher_Changed(object sender, FileSystemEventArgs e)
{
ThreadPool.QueueUserWorkItem((o) => ProcessFile(e));
}
//This method processes your file, you can do your sync here
private static void ProcessFile(FileSystemEventArgs e)
{
// Based on the eventtype you do your operation
switch (e.ChangeType)
{
case WatcherChangeTypes.Changed:
Console.WriteLine($"File is changed: {e.Name}");
break;
case WatcherChangeTypes.Created:
Console.WriteLine($"File is created: {e.Name}");
break;
case WatcherChangeTypes.Deleted:
Console.WriteLine($"File is deleted: {e.Name}");
break;
case WatcherChangeTypes.Renamed:
Console.WriteLine($"File is renamed: {e.Name}");
break;
}
}
}
}
如果您想查看多个文件夹,只需添加另一个 FileSystemWatcher 并将创建、重命名、更改和删除事件挂接到同一个事件处理程序 (FileWatcher_Changed)