因此,此应用程序在Visual Studio中无缝运行,但我为遇到错误的程序创建了一个安装程序。我想我已经确定了问题所在。当收到一个POST时,它会处理一个单独的分离进程,最终会从网页处理/关闭中取消。处理POST后线程中止
程序流程是这样
- POST接收
context.Request.HttpMethod == "POST"
, - 相关XML信息提取并写入磁盘,
csfireEyeHandler.DonJobOnLastIp()
,- 在后台运行的监视器上的文件拾取创建事件`void OnChanged'并开始基于XML文档运行服务
FileAdded
- >readerRef.ReadInServices(e.FullPath, false)
。
问题是POST处理后,它导致服务中止与ThreadAbortException。如果在服务完成后handler.ProcessRequest(context)
之后放置了延迟,我推测因为该页面仍然打开。我无法弄清楚如何正确处理这种情况,它非常难以调试,因为我无法在VS中发生错误。
public partial class fireEye : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
HttpContext context = Context;
fireEyeHandler handler = new fireEyeHandler();
handler.ProcessRequest(context);
}
}
public class fireEyeHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.HttpMethod == "POST")
{
var extension = context.Request.Url.AbsolutePath.Split('/')[2].ToLower();
var stream = context.Request.InputStream;
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
var xml = Encoding.UTF8.GetString(buffer);
FileManage.WriteToFile(xml, @"C:\ECC_output\fireEye.xml");
var csfireEyeHandler = new FireEyeService { config = extension + ".config" };
csfireEyeHandler.Load();
csfireEyeHandler.DonJobOnLastIp();
context.Response.StatusCode = 202;
}
}
public bool IsReusable
{
get { return false; }
}
}
public class Monitor
{
bool monitorIsActive;
readonly XmlRead readerRef; // Reference to the xml reader
readonly FileSystemWatcher watch;
public bool monitorRunning;
public Monitor(XmlRead reader)
{
watch = new FileSystemWatcher();
readerRef = reader;
try
{
watch.Path = @"C:\ECC_temp"; //directory to monitor
}
catch (ArgumentException ex)
{
Report.LogLine (ex.Message);
return;
}
watch.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watch.Filter = "*.xml";
monitorIsActive = true;
watch.Created += OnChanged;
watch.Deleted += OnChanged;
watch.Renamed += OnRenamed;
watch.EnableRaisingEvents = true;
}
/// <summary>
/// Toggles on/off if a directory is being monitored
/// </summary>
public void ToggleMonitor()
{
monitorIsActive = !monitorIsActive;
var monitorState = monitorIsActive ? "on" : "false";
Report.LogLine ("Monitor is " + monitorState);
}
/// <summary>
/// File has been added to the directory
/// </summary>
public bool FileAdded(FileSystemEventArgs e, XmlDocument xmlDocument)
{
try
{
var date = string.Format ("<br>\r\n**********************Report {0:yyyy MM-dd hh:mm tt}**********************", DateTime.Now);
Report.LogLine(date);
readerRef.Validate(e.FullPath, false);
readerRef.ReadInServices(e.FullPath, false);
Report.CreateReport();
}
catch (Exception exception)
{
Report.LogLine(exception.Message + " id:6");
Report.CreateReport();
return true;
}
return true;
}
/// <summary>
/// When a file is added, renamed or deleted, OnChanged is called and the appropriate action is taken
/// </summary>
private void OnChanged(object source, FileSystemEventArgs e)
{
monitorRunning = true;
while (true)
{
if (e.ChangeType == WatcherChangeTypes.Created || e.ChangeType == WatcherChangeTypes.Renamed)
{
var xmlDocument = new XmlDocument();
try
{
xmlDocument.Load(e.FullPath);
}
catch (IOException)
{
Thread.Sleep(100);
}
if (FileAdded(e, xmlDocument))
{
break;
}
}
}
monitorRunning = false;
}
}
Web应用程序对监视器一无所知。监视器从正在放入目录的xml文件启动服务。我认为,既然他们没有提到对方,也不能让另一方终止,但事实并非如此。我将尝试将FireEye处理程序移到MVC控制器,以便它不在处理的网页中。 – flaVius 2012-07-19 21:50:23
我不认为移动它会让你受益良多。我相信你在这里有一个基本的设计问题。你有一些忙于尝试读取文件的背景中,而另一些忙于尝试读取或写入这些相同的文件。要么你必须让你的文件观察器处理程序退后一步,让其他代码完成,或者通过某种方式发送创建已发生且所有写入已完成的代码。 – 2012-07-20 00:30:00
我真的不认为文件系统监视器是正确的解决方案;您可以在创建通知后添加暂停;但无论你选择什么时候暂停,总会是错误的。这一切都在同一个过程中,为什么不只是创建通知代码的代码来记录或执行报告。 – 2012-07-20 00:30:53