Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.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# 使用Rx枚举所有文件_C#_Reactive Programming - Fatal编程技术网

C# 使用Rx枚举所有文件

C# 使用Rx枚举所有文件,c#,reactive-programming,C#,Reactive Programming,这是我在文件搜索过程中使用大量文件(或来自慢速网络文件夹)创建listbox时尝试的更具响应性的界面 IDisposable observer; IObservable<IList<FileInfo>> bufferedFiles; ObservableCollection<object> _fileCollection = new ObservableCollection<object>(); public void EnumerateFile

这是我在文件搜索过程中使用大量文件(或来自慢速网络文件夹)创建listbox时尝试的更具响应性的界面

IDisposable observer;
IObservable<IList<FileInfo>> bufferedFiles;
ObservableCollection<object> _fileCollection = new ObservableCollection<object>();

public void EnumerateFiles(string myfolder, string filter)
{
    var syncContext = SynchronizationContext.Current;
    DirectoryInfo dir = new DirectoryInfo(myfolder);

    this.bufferedFiles =
     Observable.Buffer(dir.EnumerateFiles(filter, System.IO.SearchOption.AllDirectories)
    .ToObservable(NewThreadScheduler.Default), TimeSpan.FromSeconds(.2), 100, NewThreadScheduler.Default)
    .ObserveOn(syncContext); 

    this.observer = this.bufferedFiles.Subscribe(outputFiles);
}

private void outputFiles(IEnumerable<FileInfo> FI)
{
    foreach (var file in FI)
        _fileCollection.Add(file);
    Debug.Print(_fileCollection.Count.toString());
}
IDisposable观察员;
IObservable缓冲文件;
ObservableCollection_fileCollection=新的ObservableCollection();
公共文件(字符串myfolder、字符串筛选器)
{
var syncContext=SynchronizationContext.Current;
DirectoryInfo dir=新的DirectoryInfo(myfolder);
此文件为.bufferedFiles=
Observable.Buffer(目录枚举文件(过滤器,System.IO.SearchOption.AllDirectories)
.ToObservable(NewThreadScheduler.Default)、TimeSpan.FromSeconds(.2)、100、NewThreadScheduler.Default)
.ObserveOn(syncContext);
this.observer=this.bufferedFiles.Subscribe(outputFiles);
}
私有void输出文件(IEnumerable FI)
{
foreach(FI中的var文件)
_fileCollection.Add(文件);
Print(_fileCollection.Count.toString());
}
缓冲区的解释如下:

…将可观察序列的每个元素放入已发送的缓冲区中 当它已满或已过给定的时间时退出

所以我希望在本地驱动器上listbox一次可以获得100个项目,而在慢速网络上,它将在0.2秒内输出缓冲区收集的任何内容(只要小于100个项目)。我希望在另一个线程上进行枚举,而观察显然必须在dispatcher上


问题是UI被冻结了

可观察的间隔。每隔指定的时间间隔重复该操作。缓冲区刚好能满足你的愿望

private async Task OutputFiles(IEnumerable<object> paths) 
{ 
    foreach (var o in paths) 
    {
         await Task.Delay(1); // Delay so the UI can update the List
        _fileCollection.Add(o); 
    }

    this.observer = Observable.Buffer(
      dir.EnumerateFiles(
         myfile, 
         System.IO.SearchOption.AllDirectories, 
         true).ToObservable(Scheduler.Default), 
      TimeSpan.FromSeconds(.5),                      
      Scheduler.Default)
   .ObserveOn(syncContext)
   .Subscribe(async x => await outputFiles(x));
} 
专用异步任务输出文件(IEnumerable路径)
{ 
foreach(路径中的变量o)
{
等待任务。延迟(1);//延迟以便UI可以更新列表
_添加(o);
}
this.observer=Observable.Buffer(
目录文件(
我的文件,
System.IO.SearchOption.AllDirectory,
true)。ToObservable(Scheduler.Default),
时间跨度。从秒(.5),
调度程序(默认)
.ObserveOn(同步上下文)
.Subscribe(异步x=>等待输出文件(x));
} 

与哪种代码相比,它的速度较慢?你测试过不止一次吗?当您指定一个时间间隔(TimeSpan)时,它将在该时间间隔过期后开始。如果要立即启动,请指定StartWith(0)。@MartijnvanPut比不使用Rx时慢,只需在ForEach中枚举文件和.Add。为什么不在dir.EnumerateFiles上调用ToObservable并在SyncContext上观察它,然后再次检查性能?我想知道为什么要在枚举文件时使用间隔和Zip/Buffer?这种构造对非对称的情况相同吗-RX@MartijnvanPutStartWith(0)消除了恼人的延迟。谢谢使用Zip/Buffer,我试图强制输出,无论是经过0.2秒还是首先找到1000个项目。这样,用户在.2s之后至少会有一些内容。我做得对吗?间隔每.2秒重复一次,当我正确理解您时,您需要以下内容:dir.EnumerableFiles().ToObservable().Take(1000).TimeSpan.FromSeconds(.2))。此代码接受前1000个或超时(它抛出TimeoutException以便捕获它)