2017-01-04 7 views
0

Web Api 2を使用して一連のWebサービスを作成しました。結局、OpenEdge Progressクライアントを起動し、フォーマットされたXML文字列を渡した後、レコードをOpenEdge Progress (WebSpeedはオプションではありません)。ファイルが存在するまで待ちます

.Pファイルには、進捗状況アプリケーションに対して実行する一連のビジネスロジックがあります。その後、完了時に<エラー>ノードを含むXMLファイルが生成されます。このノードが空の場合、それは機能します。ファイルが存在しないか、ノードにテキストが含まれていれば失敗しました。私はこのXMLファイルを読んで、<エラー>ノードの内容をWeb APIのクライアントに返します。

現在のところ、CMD/Progressアプレットの呼び出しからXMLファイルの読み込み、.Pファイルを実行してXMLファイルを作成するためのサーバーへの静的な遅延が10秒あります。しかし、これは素晴らしいことではありません。また、ファイルが見つからないためにクライアントにエラーが返されることもありますが、サーバーロードが異常に高いために応答が返されてから1秒後にファイルが作成されました。また、応答が2秒以内に処理された場合、10秒間待つように強制されます。

タイムアウト時間が経過するまで「ファイルが存在するまでチェックする」方法を考え出す必要があります。私はいくつかの調査を行っており、Web API環境に適したものを見つけることはできません。誰にも何か提案はありますか?

コード - 私を許してください。私は一緒に行ってきたのでとても勉強してきましたし、これにはとても新しいです!コントローラ

// the request date/time 
DateTime requestDate = DateTime.Now; 
// list of validation errors 
List<string> ohValidation = new List<string>(); 

...

WebExtensions.callInsertProgram(xml, "JOBLOG"); 
ohValidation =  XmlExtensions.ReadProgressXmlFileWithArray(job.logjob.placeref, requestDate, "joblogging"); 

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; 
    } 

Delay_Start

private static void Delay_Start(int Seconds) 
    { 
     DateTime StartTime; 
     DateTime EndTime; 

     StartTime = DateTime.Now; 
     EndTime = StartTime.AddSeconds(Seconds); 

     do 
     { StartTime = DateTime.Now; } while (StartTime < EndTime); 
    } 

FullFileName(作成されるまで、私はXMLファイル名の確認することはできませんので、必要に応じて。ファイル形式はUniqueReference_DateTimeFileCreated.xml(xxxxxxxx_20160401-1100.xml)です。したがって、一意の参照でフォルダをワイルドカードで検索する必要があります。

public static string fullFileName(string jobNo, string folder, DateTime createdDate) 
    { 
     string fileName = string.Empty; 
     string folderPath = fileLocation + folder; 
     DirectoryInfo dir = new DirectoryInfo(folderPath); 
     FileInfo[] files = dir.GetFiles(jobNo + "*", SearchOption.TopDirectoryOnly).Where(f => f.CreationTimeUtc > createdDate || f.LastWriteTimeUtc > createdDate).ToArray() ; 
     foreach (var item in files) 
     { 
      fileName = item.Name; 
     } 

     if (string.IsNullOrEmpty(fileName)) 
      throw new OpenHousingException("No OpenHousing file could be found"); 

     return fileName; 
    } 

GetFullFilePath(おそらくfullFileNameに統合することができます)

private static string getFullFilepath(string filename, string folder) 
    { 
     return fileLocation + folder + @"\" + filename; 
    } 

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; 

    } 
+1

CMDプログラムは同期または非同期で実行されますか?同期している場合は、単に完了するまで待ってから、出力ファイルを読むことができます。それが非同期である場合、最も単純なアプローチは、ファイルがまだ作成されているかどうかを確認するために1秒ごとにファイルシステムをポーリングすることです: 'while(!File.Exists(" myfile.xml ")){Thread.Sleep(1000 ); } ' –

+0

ファイルが利用可能になるまで、SignalRはhttps://www.asp.net/signalrまたは手動ポーリング(HEADリクエスト)を助けるかもしれません。 – Developer

+0

@ Developer彼の質問から、私は彼がクライアントコールを同期して待っていると思いますファイルは利用可能です - できるだけ早く信頼できるようにしたいだけです。 **アダム**:これを明確にすることはできますか? –

答えて

0

OK - ので、私は、私はPROBを過度に複雑されたと思いますレム。

ファイルが存在するのを待つのではなく、私は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(); 

      // ADDED 
      p.WaitForExit(60000); 
     } 
    } 
    catch (Exception e) 
    { 
     throw new OpenHousingException(e.Message.ToString()); 
    } 

} 

これは進捗CMDアプレットが次の行に移動する前に完了していることを保証します - (それが失敗したかどうか)XMLが作成されています、その時点で。初期のテストはうまくいきます。誰もこのアプローチの問題を予見できますか?

+1

'新しいOpenHousingException(e.Message.ToString());をスローするのは良い考えではありません。 'OpenHousingException(" callInsertProgram failed "、e);をスローすることで多くの情報が失われています;内部例外として例外全体を渡し、スタックトレースのような情報をそのまま維持します。 –

関連する問題