我有一个 MVC3 Web 应用程序,用户通过该应用程序将文本文件上传到服务器上的 APP Data/Upload 文件夹。要求是将这些新上传的文件通过 FTP 传输到另一台服务器上的文件夹中。我在监视此上传文件夹的控制台应用程序中使用了 FileSystemWatcher。完全创建文件后,我将这个新生成的文件传输到 FTP 文件夹。
我担心的是,如果多个实例/用户从 Web 应用程序上传文件,我的控制台应用程序将如何处理这种情况?例如,我是否需要有一个队列并使用例如FileProcesser
下面的方法在不同的线程上处理文件?
public class FileProcessor
{
private readonly Queue<string> files = new Queue<string>();
private Thread thread;
private readonly EventWaitHandle waitHandle = new AutoResetEvent(true);
private static readonly object lockObject = new object();
private volatile bool shouldStop = false;
#region Helper methods
private static bool IsFileUploadComplete(string path)
{
try
{
using (File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
{
return true;
}
}
catch (IOException)
{
return false;
}
}
private void ProcessFile(string path)
{
// Check if Result file has been completely created / uploaded
int maximumProcessRetries = 5;
int delayBeforeRetry = 5000; //in milliseconds, 5 seconds
int attempts = 0;
while (true)
{
if (IsFileUploadComplete(path))
{
//1. Open in existing IE process on Instrument Workstation
var p = new System.Diagnostics.Process();
var s = new System.Diagnostics.ProcessStartInfo(Settings1.Default.RSLSM_URL);
s.UseShellExecute = true;
s.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
p.StartInfo = s;
p.Start();
//2. Open in new IE process on Instrument workstation
//System.Diagnostics.Process.Start("IEXPLORE.EXE", "www.yahoo.com");
break;
}
attempts += 1;
if (attempts >= maximumProcessRetries)
{
// Log error and send out notifications to RSLMS Database or Email RSLMS Admin group?
break;
}
Thread.Sleep(delayBeforeRetry);
}
// Add any logic after the file has been processed
//File.Delete(path);
}
private void Work()
{
while (!shouldStop)
{
string path = String.Empty;
lock (lockObject)
{
if (files.Count > 0)
{
path = files.Dequeue();
}
}
if (!String.IsNullOrEmpty(path))
{
// Process the file
ProcessFile(path);
}
else
{
// If no files are left to process then wait
waitHandle.WaitOne();
}
}
}
#endregion
#region Methods
public void EnqueueFile(string path)
{
// Queue the file
lock (lockObject)
{
files.Enqueue(path);
}
// Initialize and start the worker thread when the first file is queued
// or when it has been stopped and thus terminated.
if (thread == null || shouldStop)
{
thread = new Thread(new ThreadStart(Work));
thread.Start();
}
// If the thread is waiting then start it
else if (thread.ThreadState == ThreadState.WaitSleepJoin)
{
waitHandle.Set();
}
}
public void StopProcessing()
{
shouldStop = true;
}
#endregion
}