2012-02-22 8 views
-5

私は、ディレクトリ内のファイルを読み込み、ファイル内のデータを使ってSMSを送信するタイマーイベントを発生させるC#アプリケーション(Windowsサービス)を持っています。次回イベントが発生すると、新しいファイルを処理する前に、 "処理済み"ディレクトリの処理済みファイルを "完了済み"ディレクトリに移動しようとします。私は、ファイルを使用するすべてのものを処分することはかなり確信していますが、「別のプロセスで使用中のファイル」の例外を取得し続けています。サービスを停止してもう一度起動すると、ファイルが解放されます。何か案は?Streamreaderはファイルをロックします

//Code that fires the timer  
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Linq; 
using System.ServiceProcess; 
using System.Text; 
using System.Timers; 

namespace SmsWindowsService 
{ 
    public partial class SmsWindowsService : ServiceBase 
    { 
     private static System.Timers.Timer aTimer; 

     public SmsWindowsService() 
     { 
      InitializeComponent(); 

      if (!System.Diagnostics.EventLog.SourceExists("MatterCentreSMSSource")) 
      { 
       System.Diagnostics.EventLog.CreateEventSource(
        "MatterCentreSMSSource", "MatterCentreSMSLog"); 
      } 
      elMatterCentreSMS.Source = "MatterCentreSMSSource"; 
      elMatterCentreSMS.Log = "MatterCentreSMSLog"; 

     } 

     protected override void OnStart(string[] args) 
     { 
      string logText = string.Empty; 

      logText = "MatterCentreSMS Service started successfully on " + DateTime.Now; 

      WriteEventLog(logText); 

      //Create a timer with a ten second interval. 
      aTimer = new System.Timers.Timer(10000); 

      //Hook up the Elapsed event for the timer. 
      aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 

      //Set the Interval to 5 minutes. 
      //aTimer.Interval = 300000; 
      aTimer.Interval = 60000; 
      aTimer.Enabled = true; 

      // If the timer is declared in a long-running method, use 
      // KeepAlive to prevent garbage collection from occurring 
      // before the method ends. 
      //GC.KeepAlive(aTimer); 
      GC.Collect(); 
     } 

     protected override void OnStop() 
     { 
      string logText = string.Empty; 

      logText = "MatterCentreSMS Service stopped on " + DateTime.Now; 

      WriteEventLog(logText); 
     } 

     private void WriteEventLog(string logText) 
     { 
      elMatterCentreSMS.WriteEntry(logText); 
     } 

     private void OnTimedEvent(object source, ElapsedEventArgs e) 
     { 
      string ex = string.Empty; 

      SendSms s = new SendSms(); 

      ex = s.ProcessSms(); 

      if (ex.Length > 1) 
       WriteEventLog(ex); 

      //ex = RestartService("SmsWindowsService", 60000); 
      //WriteEventLog(ex); 
     } 

     public string RestartService(string serviceName, int timeoutMilliseconds) 
     { 
      ServiceController service = new ServiceController(serviceName); 

      try 
      { 
       int millisec1 = Environment.TickCount; 
       TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); 

       service.Stop(); 
       service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); 

       // count the rest of the timeout 
       int millisec2 = Environment.TickCount; 
       timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1)); 

       service.Start(); 
       service.WaitForStatus(ServiceControllerStatus.Running, timeout); 

       return "MatterCentreSMS Service successfully restarted on " + DateTime.Now; 
      } 

      catch (Exception e) 
      { 
       return Convert.ToString(e); 
      } 
     } 
    } 
} 

//Code that reads the file 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Xml; 

namespace SmsWindowsService 
{ 
    class Message 
    { 
     private string filePath; 

     public Message(string filePath) 
     { 
      this.filePath = filePath; 
     } 

     public string readSMS(string filePath) 
     { 
      const string searchmessage = "[B-->]"; 
      StreamReader smsmessage = new StreamReader(filePath); 

      try 
      { 
       FileInfo filenameinfo = new FileInfo(filePath); 
       if (filenameinfo.Exists == false) 
        throw new SMSReaderException(String.Format("SMS Message {0} cannot be found ...", filePath), filePath); 

       smsmessage = filenameinfo.OpenText(); 
       string smsoutput = smsmessage.ReadToEnd(); 
       int endpos = smsoutput.IndexOf(searchmessage); 
       smsoutput = smsoutput.Substring(endpos + searchmessage.Length); 
       smsoutput = smsoutput.Replace("&", "&"); 
       smsoutput = smsoutput.Replace("\"", """); 
       smsoutput = smsoutput.Replace("'", "'"); 

       filenameinfo = null; 
       smsmessage.Close(); 
       smsmessage.Dispose(); 

       return smsoutput; 
      } 

      catch(Exception e) 
      { 
       throw new Exception("Help", e.InnerException); 
      } 

      finally 
      { 
       smsmessage.Close(); 
       smsmessage.Dispose(); 
      } 
     } 
    } 

    public class SMSReaderException : System.IO.FileNotFoundException 
    { 
     public SMSReaderException(string message, string filename) 
      : base(message, filename) 
     { 
     } 
    } 
    } 

//Code that connects to web service and send sms 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 
using System.Data; 
using System.IO; 
using System.Net; 
using System.Configuration; 
using SmsWindowsService.EsendexSendSmsService; 

namespace SmsWindowsService 
{ 
    class SendSms 
    { 
     string filePath = string.Empty; 
     string directoryPath = string.Empty; 
     string directoryPathProcessing = string.Empty; 
     string directoryPathCompleted = string.Empty; 
     string smsLogfileDirectory = string.Empty; 
     string smsLogfilePath = string.Empty; 
     string mattercentreSMS = string.Empty; 
     string messageBody = string.Empty; 
     string messageId = string.Empty; 
     string messageStatus = string.Empty; 
     string dateTodayString = string.Empty; 
     long mobileNumber; 
     EsendexSendSmsService.SendService send; 

     public SendSms() 
     { 
      directoryPath = ConfigurationSettings.AppSettings[@"directoryPath"]; 
      directoryPathProcessing = ConfigurationSettings.AppSettings[@"directoryPathProcessing"]; 
      directoryPathCompleted = ConfigurationSettings.AppSettings[@"directoryPathCompleted"]; 
      smsLogfileDirectory = ConfigurationSettings.AppSettings[@"smsLogfileDirectory"];    
      dateTodayString = DateTime.Now.ToString("yyyy/MM/dd"); 
      smsLogfilePath = smsLogfileDirectory + dateTodayString.Replace(@"/", "_") + ".txt"; 
      send = new EsendexSendSmsService.SendService(); 
     } 

     public string ProcessSms() 
     { 
      string ex = string.Empty; 

      try 
      { 
       DirectoryInfo di = new DirectoryInfo(directoryPathProcessing); 

       ex = MoveFilesToCompleted(directoryPathProcessing, directoryPathCompleted); 

       if (ex.Length > 1) 
        return ex; 

       ex = MoveFilesToProcessing(directoryPath, directoryPathProcessing); 

       if (ex.Length > 1) 
        return ex; 

       FileInfo[] subFilesProcessing = di.GetFiles(); 

       foreach (FileInfo subFile in subFilesProcessing) 
       { 
        filePath = directoryPathProcessing + subFile.Name; 

        Message sms = new Message(filePath); 

        mattercentreSMS = sms.readSMS(filePath); 

        MessageDetails d = new MessageDetails(mattercentreSMS); 

        mobileNumber = d.GetMobileNumber(); 
        messageBody = d.GetMessageBody(); 

        ex = SetHeader(); 

        if (ex.Length > 1) 
         return ex; 

        ex = SetProxy(); 

        if (ex.Length > 1) 
         return ex; 

        //Send the message and get the returned messageID and send status 
        messageId = send.SendMessage(Convert.ToString(mobileNumber), messageBody, EsendexSendSmsService.MessageType.Text); 
        messageStatus = Convert.ToString(send.GetMessageStatus(messageId)); 

        ex = WriteLogFile(messageId, subFile.Name, messageStatus); 

        if (ex.Length > 1) 
         return ex; 

        send.Dispose(); 
       } 

       di = null; 
       subFilesProcessing = null; 

       return ex; 
      } 

      catch (Exception e) 
      { 
       return Convert.ToString(e); 
      } 
     } 

     private string MoveFilesToCompleted(string directoryPathProcessing, string directoryPathCompleted) 
     { 
      DirectoryInfo din = new DirectoryInfo(directoryPathProcessing); 

      try 
      {     
       FileInfo[] subFiles = din.GetFiles(); 

       foreach (FileInfo subFile in subFiles) 
       { 
        subFile.MoveTo(directoryPathCompleted + subFile.Name); 
       } 

       subFiles = null; 
       return "";     
      } 

      catch (Exception e) 
      { 
       return Convert.ToString(e); 
      } 

      finally 
      { 
       din = null; 
      } 
     } 

     private string MoveFilesToProcessing(string directoryPath, string directoryPathProcessing) 
     { 
      DirectoryInfo din = new DirectoryInfo(directoryPath); 

      try 
      { 
       FileInfo[] subFiles = din.GetFiles(); 

       foreach (FileInfo subFile in subFiles) 
       { 
        subFile.MoveTo(directoryPathProcessing + subFile.Name); 
       } 

       subFiles = null; 
       return ""; 
      } 

      catch (Exception e) 
      { 
       return Convert.ToString(e); 
      } 

      finally 
      { 
       din = null; 
      } 
     } 

     private string SetHeader() 
     { 
      try 
      { 
       //Setup account details in the header 
       EsendexSendSmsService.MessengerHeader header = new EsendexSendSmsService.MessengerHeader(); 
       header.Account = ConfigurationSettings.AppSettings[@"smsServiceUrl"]; 
       header.Username = ConfigurationSettings.AppSettings[@"smsServiceUsername"]; 
       header.Password = ConfigurationSettings.AppSettings[@"smsServicePassword"]; 

       // set the SOAP header Authentication values 
       send.MessengerHeaderValue = header; 

       return ""; 
      } 

      catch (Exception e) 
      { 
       return Convert.ToString(e); 
      } 
     } 

     private string SetProxy() 
     { 
      try 
      { 
       //Create a web proxy object as the proxy server block direct request to esendex 
       WebProxy myProxy = new WebProxy(ConfigurationSettings.AppSettings[@"proxyaddress"], true); 
       myProxy.Credentials = new NetworkCredential(ConfigurationSettings.AppSettings[@"username"], ConfigurationSettings.AppSettings[@"password"]); 
       WebRequest.DefaultWebProxy = myProxy; 
       send.Proxy = myProxy; 

       return ""; 
      } 

      catch (Exception e) 
      { 
       return Convert.ToString(e); 
      } 
     } 

     private string WriteLogFile(string messageId, string smsFileName, string messageStatus) 
     { 
      try 
      { 
       if (File.Exists(smsLogfilePath)) 
       { 
        //file is not empty - append log entry to file 
        using (StreamWriter writeSmsLog = File.AppendText(smsLogfilePath)) 
        { 
         writeSmsLog.WriteLine(messageId + "    " + smsFileName + " " + DateTime.Now + "  " + messageStatus); 
         writeSmsLog.Close(); 
        } 
       } 
       else 
       { 
        FileStream fs = File.OpenWrite(smsLogfilePath); 
        fs.Flush(); 
        fs.Close(); 
        fs.Dispose(); 

        using (StreamWriter writeSmsLog = new StreamWriter(smsLogfilePath, true)) 
        { 
         writeSmsLog.WriteLine("Message_ID          File_Name         Date_Sent     Status"); 
         writeSmsLog.WriteLine("======================================================================================================================================"); 
         writeSmsLog.WriteLine(messageId + "    " + smsFileName + " " + DateTime.Now + "  " + messageStatus); 
         writeSmsLog.Close(); 
        } 
       } 

       return ""; 
      } 

      catch (Exception e) 
      { 
       return Convert.ToString(e); 
      } 
     } 
    } 
} 
+6

-1本当にすべてのコードを投稿する必要がありましたか? –

+4

質問に投稿されたコードを、問題の例となる関連部分またはサンプルに制限してください。 –

+0

私はむしろ必要以上のコードを追加し、漠然とした質問をしている人にイライラさせるよりも、達成しようとしていることを誰もが明確に理解できるようにしてください。 – marius

答えて

1
StreamReader smsmessage = new StreamReader(filePath); 

try 
{ 
    FileInfo filenameinfo = new FileInfo(filePath); 
    .... 
    smsmessage = filenameinfo.OpenText(); 
    ... 

smsmessageは2回初期化されますが、そのうちの1つのインスタンスのみが破棄されます。最初の行はStreamReaderを作成し、そのインスタンスへの参照をfilenameinfo.OpenText()によって作成されたインスタンスで上書きします。それは、もはや参照を持たず、処分されていないインスタンスを残します。このインスタンスはファイルをロックしている可能性があり、破棄されるタイミングは保証されません。ロックを保持していない場合でも、これを修正する必要があります。

+0

ありがとう、本当にあなたの助けに感謝します。 – marius

7

任意のアイデア?

あなたは全く異なるプロセスでウイルスチェッカーを実行しています。ファイルが変更されたことを検出していて、ファイルに対して直前に実行した編集がウイルスを導入したかどうかを確認するために、一時的にロックしています。それは数ミリ秒でロックを解除します。

ウィルスチェッカーを無効にすることは悪い考えです。代わりに、あなたはそれだけで生活しなければならないでしょう。ファイルのロックを争う多くのプロセスが存在する世界で堅牢になるようにコードを書いてください。

+0

:これも問題だとも考えました。ご覧のように、イベントは1分ごとに発生します。私は5分ごとに発砲するイベントでもテストしましたが、違いはありません。提案していただきありがとうございます。 – marius

関連する問題