![](/img/trans.png)
[英]What is the better way to implement a C# thread to process functions to get data on database without lock user interface
[英]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服務或調度程序運行。 因此,我確實需要后台工作人員定期清理丟失的文件。 我簽出了Timer
和WaitHandles
但不太確定如何使用它們實現以下功能。
在主應用程序線程中,我將實例化該類並在應用程序啟動時調用方法,這兩個過程(新文件的主偶處理程序和后台清理程序的調用方式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.