我创建这将不定期检查,如果有一定的存在窗口服务,如果确实如此,那么从中读取,将数据发送到服务器和文件移动到另一个文件夹。 文件的大小约为1-3 MB。
我想我会用System.Threading.Timer
这里来检查文件是否存在。 你怎么看呢?
而另一个问题。 如果一个文件被复制,然后我的应用程序不能读取它。 应该等到复制完成。 只有在此之后,必须从中读取并执行其他活动。
所以问题:
1)是一个正确的决定使用System.Threading.Timer
?
2)我如何检查文件被复制并等待它完成?
3)我必须使用多线程?
我用通常的方法是监视文件夹/ s的FileSystemWatcher的(或相关的API如果不是.NET托管),并尝试以确保操作只有在源/目标文件夹进行的移动/文件夹重命名之间在同一个物理驱动器上,并删除。 如果你想添加一个文件,打开/写/平/关闭它ITO目标文件系统驱动器上的临时文件夹,然后才移动/重命名文件夹被监视。 至关重要的是,临时文件夹是在同一个物理驱动器作为目标文件夹,以便它可以是移动/无数据复制重命名。
这适用于非管理系统,而不是试图在C#中,但看不出有任何理由不上班确定。
涉及持续轮询和/或检查文件大小的其他解决方案都只是不方便,不灵活,浪费,混乱和延迟缠身的最好的。
多线程 - 任何远程文件系统或许是肯定的。 网络文件调用往往对unrechability等很长的超时等阻塞调用者什么似乎像永远发出错误/异常之前。 如果你想获得什么都做,你应该线头脱落了很多,除非你的用户可以容忍“沙漏应用”,与Windows变得反应迟钝,消失到后,让灰色显示和操作系统提供关闭它们。
哦,还有另一件事 - 最好在启动时去清洗。 东西可以在任何时候出问题了,所以跑起来时从清理临时文件夹等任何挥之不去的垃圾。
我想我会用System.Threading.Timer
这里来检查文件是否存在。 你怎么看呢?
我想你不妨来看看在FileSystemWatcher
类文件创建时将通知您,并使用定时器,将不断为文件是否存在轮询引发事件,而不是你。
定时器是非常昂贵的。 您可以使用FileSystemWatcher
侦听文件系统更改通知,并当目录或文件目录中,变化引发事件。
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = /*path*/
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
// Begin watching.
watcher.EnableRaisingEvents = true;
那么这将是OnChanged
方法:
//This method is called when a file is created, changed, or deleted.
private static void OnChanged(object source, FileSystemEventArgs e)
{
//Show that a file has been created, changed, or deleted.
WatcherChangeTypes wct = e.ChangeType;
Console.WriteLine("File {0} {1}", e.FullPath, wct.ToString());
}
参考: http://devproconnections.com/net-framework/how-build-folder-watcher-service-c
我不会使用FileSystemWatcher的它太片状
FileSystemWatcher的没有从Windows服务中创建的文件工作
我会用定时器设定一个合理的蜱期间,你应该没问题。
一些示例代码
Timer_TicK()
{
// remove tick event handler
// do your processing
// add back tick event handler
}
这将保持多蜱的活动从,如果你有一个相当大的加工量做的事情。 我不会多线程,直到你找到你需要用它由于性能问题。
在C#中,如果你尝试读取文件,而它的由文件系统,你会得到一个异常复制。 您需要检查是否有异常或检查文件(大小等)的属性,当它这样做就知道了。
全定时器例如,当我开始每间隔发生时(你没有,但它是一个很好的做法),它去,并检查该文件是否存在,并读取它,并删除它,如果它是新主题:
using System;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
using System.IO;
namespace MyNamespace
{
public partial class Service1: ServiceBase
{
Thread syncThread = null;
System.Timers.Timer timer1;
string filePath = @"C:\myfile.txt";
int interval = 60000; // 1 min -- adjust as necessary
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer1 = new System.Timers.Timer();
timer1.Interval = interval;
timer1.Enabled = true;
timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
timer1.Start();
}
protected override void OnStop()
{
syncThread.Abort();
timer1.Stop();
}
protected void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
syncThread = new Thread(new ThreadStart(doThread));
syncThread.Start();
}
protected void doThread()
{
// whatever you put here, it will
// run for each timer interval that elapses
// in a separate thread, and each thread will
// end when the processing in this function ends
string fileContent = String.Empty;
if (File.Exists(filePath)
{
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
fileContent = sr.ReadToEnd();
sr.Close();
fs.Close();
}
if (fileContent != String.Empty)
{
// File was present... process the content...
// Then I do this...
File.Delete();
}
}
}
}
我已经没有任何问题跑了。 我更愿意开始新的线程,每个时间间隔,因此不会造成问题,如果以前的运行还没有完成。 走这条路,你有控制,可以决定你的时间间隔是什么,以及你的进程并不总是要去 - 仅仅是服务。 另一条路线,与FileSystemWatcher
,它总是观察和运行时,它可以和你不能调整的时间间隔,比如你可以用一个定时器,以保持下来的事件数/处理事情,例如当/如果文件创建,然后迅速修改和保存。
唯一的缺点我看到的是有来检查文件属性自己,但这些都是很容易的进行检查,以。 如果你File.Delete()
处理之后像我这样做,你只有File.Exists(filePath)
做,以找出是否该文件已被重新创建。 如果你有检查修改,你只是检查DateTime lastModifed = File.GetLastWriteTime(filePath)
(见http://www.csharp-examples.net/file-creation-modification-time/ )针对当前时间+您的间隔(这将是DateTime lastRun = DateTime.Now.AddMilliseconds(interval)
)。 如果lastRun > lastModified
,你必须处理它。