簡體   English   中英

在C#中實現以下長時間運行的線程的更好方法

[英]Better way to implement the following long running thread in C#

我有一個具有主線程的應用程序,該主線程等待事件(例如,接收目錄中的文件)並將該文件發布到API。 這部分工作正常。

另一方面,由於某些原因,主線程可能會丟失某些文件。 因此,我設置了一個后台線程以在應用程序的整個生命周期中運行,以清除那些丟失的文件,如下所示:

public virtual void MissedFileHandler()
{
     if (_missedFileHandlerThread == null || !_missedFileHandlerThread.IsAlive)
     {
          _missedFileHandlerThread = new Thread(new ThreadStart(ClearMissedFiles));
          _missedFileHandlerThread.IsBackground = true;
          _missedFileHandlerThread.Start();
     }
}

protected virtual void ClearMissedFiles()
{
     while (true)
     {
         string[] missedFiles = new string[] { };
         missedFiles = Directory.GetFiles(ConfigurationHelper.applicationRootDirectory, "*.txt", SearchOption.TopDirectoryOnly);
         Parallel.ForEach(missedFiless, (currentMissedFile) =>
         {
             bool isFileInUse = true;
             isFileInUse = FileHelper.CheckIfFileInUse(filesInUseCollection, currentMissedFile)
             if (!isFileInUse)
             {
                 bool isHttpTransferSuccess = false;
                 isHttpTransferSuccess = FileHelper.SendFileToApi(userid, currentMissedFile);
             if (isHttpTransferSuccess)
             {
                  File.Delete(currentMissedFile);

             }
         }
     });
     Thread.Sleep(1000);
     }
  }

請注意,由於某些其他原因,不能將其作為Windows服務或調度程序運行。 因此,我確實需要后台工作人員定期清理丟失的文件。 我簽出了TimerWaitHandles但不太確定如何使用它們實現以下功能。

在主應用程序線程中,我將實例化該類並在應用程序啟動時調用方法,這兩個過程(新文件的主偶處理程序和后台清理程序的調用方式Thread.Sleep()Thread.Sleep()while (true) ,這困擾着我,並且正在尋找更好的方法。謝謝。

您可以使用文件監視程序來檢測該目錄中的新文件。

private void watch()
{
  FileSystemWatcher watcher = new FileSystemWatcher();

  // Set your path with this
  watcher.Path = path;

  // Subscribe to event
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

嘗試使用Microsoft的Reactive Framework。 然后,您可以執行以下操作:

IObservable<Unit> fileChanges =
    Observable
        .Using(() =>
        {
            var fsw = new FileSystemWatcher();
            fsw.Path = path;
            fsw.EnableRaisingEvents = true;
            return fsw;
        }, fsw =>
            Observable
                .FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
                    h => fsw.Changed += h,
                    h => fsw.Changed -= h))
        .Select(ep => Unit.Default);

IObservable<Unit> periodically =
    Observable
        .Interval(TimeSpan.FromSeconds(30.0))
        .Select(x => Unit.Default);

IObservable<string> clearMissedFiles =
    fileChanges
        .Merge(periodically)
        .SelectMany(u => Directory.GetFiles(ConfigurationHelper.applicationRootDirectory, "*.txt", SearchOption.TopDirectoryOnly))
        .Where(f => !FileHelper.CheckIfFileInUse(filesInUseCollection, f))
        .SelectMany(f => Observable.Start(() => FileHelper.SendFileToApi(userid, f)), (f, s) => new { file = f, success = s })
        .Where(x => x.success)
        .Select(x => x.file);

IDisposable subscription =
    clearMissedFiles
        .Subscribe(f => File.Delete(f));

這會監視文件系統並定期檢查。 並以並行方式調用該API,並且不會因嘗試一次刪除多個文件而導致操作系統痛苦。

只需在退出之前調用subscription.Dispose()進行清理即可。

NuGet“ System.Reactive”為位,然后using System.Reactive.Linq引用以顯示擴展名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM