C# 等待文件存在
我已经使用WebAPI2编写了一组web服务。他们最终会调用一个CMD程序,启动OpenEdge进程客户端,传递格式化的XML字符串,然后通过调用.p过程将记录插入OpenEdge进程数据库(WebSpeed不是选项) p文件有一组针对进度应用程序运行的业务逻辑。它随后在完成时生成一个包含C# 等待文件存在,c#,asp.net,asp.net-web-api,C#,Asp.net,Asp.net Web Api,我已经使用WebAPI2编写了一组web服务。他们最终会调用一个CMD程序,启动OpenEdge进程客户端,传递格式化的XML字符串,然后通过调用.p过程将记录插入OpenEdge进程数据库(WebSpeed不是选项) p文件有一组针对进度应用程序运行的业务逻辑。它随后在完成时生成一个包含节点的XML文件。如果这个节点是空的,那么它工作了。如果文件不存在或节点包含文本。。。它失败了。然后,我读取这个XML文件,并在Web Api中将节点的内容传递回客户机 目前,从调用CMD/Progress小程
// the request date/time
DateTime requestDate = DateTime.Now;
// list of validation errors
List<string> ohValidation = new List<string>();
CallInsertProgram
public static void callInsertProgram(string xml, string program)
{
try
{
using (Process p = new Process())
{
p.StartInfo.FileName = @"C:\Rubixx\runProgress.exe";
p.StartInfo.WorkingDirectory = @"C:\Rubixx";
// stop windows from appearing on the server
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
// set the arguments for running. The program name and xml are passed in as arguments
// wrapped in escaping "\" to stop spaces from being treated as a separator
p.StartInfo.Arguments = "\"" + program + "," + xml + "\"";
p.Start();
}
}
catch (Exception e)
{
throw new OpenHousingException(e.Message.ToString());
}
}
ReadProgressXMLWithArray
public static List<string> ReadProgressXmlFileWithArray(string reference, DateTime requestDateTime, string folder)
{
// new empty list
List<string> output
= new List<string>();
// wait X seconds before doing anything
// to ensure the XML file has time to be created
Delay_Start(fileDelay);
//
string filename = fullFileName(jobno, folder, requestDateTime);
string filepath = getFullFilepath(filename, folder);
if (checkXmlFileExists(filepath))
{
// if so check for the existence of an error message
output = getXmlErrorArray(filepath);
}
else
{
// if no file is found - the call to Progress hasn't executed. So tell the end user.
throw new OpenHousingException("No OpenHousing file could be found");
}
return output;
}
GetFullFilePath(可能合并为fullFileName)
CheckXMLFileExists
private static bool checkXmlFileExists(string filepath)
{
bool fileExists = false;
if (File.Exists(filepath))
{
fileExists = true;
}
return fileExists;
}
GetXMLErrorArray
private static List<string> getXmlErrorArray(string filepath)
{
List<string> output
= new List<string>();
// read the text from XML file
using (TextReader txtReader = new StreamReader(filepath))
{
XmlSerializer xs
= new XmlSerializer(typeof(JobError));
// de-serialise the xml text
// to a strongly typed object
JobError result = (JobError)xs.Deserialize(txtReader);
// if the xml file contains an error - return it to the client
if (!string.IsNullOrEmpty(result.ErrorText))
output.Add(result.ErrorText);
//check for SoR errors that are created under a different node
if (result.LineError != null)
{
List<LineError> lineErrs = result.LineError.ToList();
foreach (LineError le in lineErrs)
{
output.Add(le.SorCode + ":" + le.Error);
}
}
}
return output;
}
私有静态列表getXmlErrorArray(字符串文件路径)
{
列表输出
=新列表();
//从XML文件中读取文本
使用(TextReader txtReader=新的StreamReader(文件路径))
{
XmlSerializer xs
=新的XmlSerializer(typeof(JobError));
//对xml文本进行反序列化
//对于强类型对象
JobError结果=(JobError)xs.Deserialize(txtReader);
//如果xml文件包含错误-将其返回给客户端
如果(!string.IsNullOrEmpty(result.ErrorText))
output.Add(result.ErrorText);
//检查在不同节点下创建的SoR错误
if(result.LineError!=null)
{
List lineErrs=result.LineError.ToList();
foreach(LineError中的LineError le)
{
output.Add(le.SorCode+“:”+le.Error);
}
}
}
返回输出;
}
好的-所以我认为我把问题复杂化了
我没有等待文件存在,而是在CallInsertProgram方法中添加了一行,如下所示(如RB建议的那样)
public static void callInsertProgram(string xml, string program)
{
try
{
using (Process p = new Process())
{
p.StartInfo.FileName = @"C:\Rubixx\runProgress.exe";
p.StartInfo.WorkingDirectory = @"C:\Rubixx";
// stop windows from appearing on the server
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
// set the arguments for running. The program name and xml are passed in as arguments
// wrapped in escaping "\" to stop spaces from being treated as a separator
p.StartInfo.Arguments = "\"" + program + "," + xml + "\"";
p.Start();
// ADDED
p.WaitForExit(60000);
}
}
catch (Exception e)
{
throw new OpenHousingException(e.Message.ToString());
}
}
这可以确保在移动到下一行之前完成Progress cmd applet,此时将创建XML(如果失败,则不创建)。初始测试运行良好。有人能预见这种方法会出现任何问题吗?CMD程序是同步运行还是异步运行?如果是同步运行,则您只需等待测试完成,然后读取输出文件。如果是异步运行,则最简单的方法是每1秒轮询一次文件系统,查看是否文件已创建:
while(!file.Exists(“myfile.xml”){Thread.Sleep(1000);}
signar可能有帮助-或手动轮询(HEAD请求)以固定的时间间隔,直到文件available@Developer从他的问题来看,我认为他可以同步地等待客户呼叫,直到文件可用。他只是想确保这是尽可能快和可靠的。亚当:你能澄清一下吗?@RB。-在这种情况下,他一开始就不会出现这个错误。目前re是从调用CMD/Progress小程序到尝试读取XML文件的静态延迟10秒->我认为读取XML文件是另一种延迟call@Developer我明白你的意思了-我读到所有这些都发生在一个调用的上下文中,因为行,然后我读取这个XML文件并传递节点的内容回到Web Api中的客户端。
-Adam:您肯定需要澄清-这里是有1个HTTP调用,还是有2个?!抛出新OpenHousingException(e.Message.ToString());
不是一个好主意。您正在丢失大量信息,执行抛出新OpenHousingException(“callInsertProgram失败”,e);
将整个异常作为内部异常传入,并将堆栈跟踪等信息保持不变。
private static string getFullFilepath(string filename, string folder)
{
return fileLocation + folder + @"\" + filename;
}
private static bool checkXmlFileExists(string filepath)
{
bool fileExists = false;
if (File.Exists(filepath))
{
fileExists = true;
}
return fileExists;
}
private static List<string> getXmlErrorArray(string filepath)
{
List<string> output
= new List<string>();
// read the text from XML file
using (TextReader txtReader = new StreamReader(filepath))
{
XmlSerializer xs
= new XmlSerializer(typeof(JobError));
// de-serialise the xml text
// to a strongly typed object
JobError result = (JobError)xs.Deserialize(txtReader);
// if the xml file contains an error - return it to the client
if (!string.IsNullOrEmpty(result.ErrorText))
output.Add(result.ErrorText);
//check for SoR errors that are created under a different node
if (result.LineError != null)
{
List<LineError> lineErrs = result.LineError.ToList();
foreach (LineError le in lineErrs)
{
output.Add(le.SorCode + ":" + le.Error);
}
}
}
return output;
}
public static void callInsertProgram(string xml, string program)
{
try
{
using (Process p = new Process())
{
p.StartInfo.FileName = @"C:\Rubixx\runProgress.exe";
p.StartInfo.WorkingDirectory = @"C:\Rubixx";
// stop windows from appearing on the server
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
// set the arguments for running. The program name and xml are passed in as arguments
// wrapped in escaping "\" to stop spaces from being treated as a separator
p.StartInfo.Arguments = "\"" + program + "," + xml + "\"";
p.Start();
// ADDED
p.WaitForExit(60000);
}
}
catch (Exception e)
{
throw new OpenHousingException(e.Message.ToString());
}
}