Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中实现以下长时间运行线程的更好方法#_C#_Multithreading_While Loop - Fatal编程技术网

C# 在C中实现以下长时间运行线程的更好方法#

C# 在C中实现以下长时间运行线程的更好方法#,c#,multithreading,while-loop,C#,Multithreading,While Loop,我有一个应用程序,它有一个主线程,等待一个事件(例如,接收目录中的文件)并将该文件发布到API。这部分工作正常 另一方面,由于某些原因,主线程可能遗漏了一些文件。因此,我设置了一个后台线程,在应用程序的整个生命周期中运行,以清理丢失的文件,如下所示: public virtual void MissedFileHandler() { if (_missedFileHandlerThread == null || !_missedFileHandlerThread.IsAlive)

我有一个应用程序,它有一个主线程,等待一个事件(例如,接收目录中的文件)并将该文件发布到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()
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;
}

您可以使用文件监视程序来检测该目录中的新文件

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的反应式框架。然后您可以执行以下操作:

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));
IObservable文件更改=
可观察
.使用(()=>
{
var fsw=new FileSystemWatcher();
fsw.Path=Path;
fsw.EnableRaisingEvents=true;
返回fsw;
},fsw=>
可观察
.FromEventPattern(
h=>fsw.Changed+=h,
h=>fsw.Changed-=h)
.Select(ep=>Unit.Default);
可周期观测=
可观察
.间隔(时间跨度从秒(30.0))
.Select(x=>Unit.Default);
IObservable ClearMissedFile=
文件更改
.合并(定期)
.SelectMany(u=>Directory.GetFiles(ConfigurationHelper.applicationRootDirectory,“*.txt”,SearchOption.TopDirectoryOnly))
.Where(f=>!FileHelper.checkifileinuse(filesinuscollection,f))
.SelectMany(f=>Observable.Start(()=>FileHelper.SendFileToApi(userid,f)),(f,s)=>new{file=f,success=s})
.其中(x=>x.success)
.Select(x=>x.file);
IDisposable订阅=
clearMissedFiles
.Subscribe(f=>File.Delete(f));
这会监视文件系统并定期检查,并并行调用API,同时尝试删除多个文件不会导致O/S的痛苦

在退出之前,只需调用subscription.Dispose()进行清理


NuGet“System.Reactive”用于bits,然后使用System.Reactive.Linq引用
以显示扩展。

尝试使用Microsoft的Reactive框架。然后可以执行以下操作:

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));
IObservable文件更改=
可观察
.使用(()=>
{
var fsw=new FileSystemWatcher();
fsw.Path=Path;
fsw.EnableRaisingEvents=true;
返回fsw;
},fsw=>
可观察
.FromEventPattern(
h=>fsw.Changed+=h,
h=>fsw.Changed-=h)
.Select(ep=>Unit.Default);
可周期观测=
可观察
.间隔(时间跨度从秒(30.0))
.Select(x=>Unit.Default);
IObservable ClearMissedFile=
文件更改
.合并(定期)
.SelectMany(u=>Directory.GetFiles(ConfigurationHelper.applicationRootDirectory,“*.txt”,SearchOption.TopDirectoryOnly))
.Where(f=>!FileHelper.checkifileinuse(filesinuscollection,f))
.SelectMany(f=>Observable.Start(()=>FileHelper.SendFileToApi(userid,f)),(f,s)=>new{file=f,success=s})
.其中(x=>x.success)
.Select(x=>x.file);
IDisposable订阅=
clearMissedFiles
.Subscribe(f=>File.Delete(f));
这会监视文件系统并定期检查,并并行调用API,同时尝试删除多个文件不会导致O/S的痛苦

在退出之前,只需调用subscription.Dispose()
进行清理


NuGet“System.Reactive”表示位,然后使用System.Reactive.Linq引用
表示要显示的扩展名。

使用文件监视程序检测该目录中的新文件。如果此后台任务是“有能力的”如果要做与主线程相同的工作,为什么他们两个都要做这项工作?为什么不将所有工作都留给后台线程?使用文件监视程序检测该目录中的新文件。如果此后台任务“有能力”作为主线程做同样的工作,为什么他们两个都做这个工作?为什么不把它全部留给后台线程呢?谢谢!我会尝试一下,看看它是否适用于我的用例。如果它工作可靠,我可能完全可以避免使用两个线程。如果它工作正常,我将接受作为答案。此代码的问题将是responding失败。文件正在使用吗?HTTP传输是否成功。此答案是一个良好的开始,但不是一个完整的解决方案。谢谢!我将尝试此方法,看看它是否适用于我的用例。如果此方法工作可靠,我可以完全避免使用两个线程。如果此方法有效,我将接受作为答案。此代码的问题将是be响应失败。文件是否正在使用?HTTP传输是否成功。此答案是一个良好的开端,但不是一个完整的解决方案。