我已经设置了一个文件监视程序,以便在文件更改时为我创建一个可观察的滴答声流。然后将其用作触发条件,以启动另一个重复的可观察序列,然后从开放流中读取更新的文件内容。
我遇到的问题是,如果文件更新快速连续大批量发生,则代码会在消息中抛出InvalidOperationException
该流的先前操作当前正在使用该流。
堆栈跟踪
at System.IO.StreamReader.CheckAsyncTaskInProgress()
at System.IO.StreamReader.ReadLineAsync()
at System.Reactive.Linq.QueryLanguage.StartAsyncImpl[TSource](Func`1 functionAsync, IScheduler scheduler) in D:\a\1\s\Rx.NET\Source\src\System.Reactive\Linq\QueryLanguage.Async.cs:line 676
我的RX管道可能出了什么问题?
var fileSystemWatcherChanges =
Observable
.Using(() =>
new FileSystemWatcher(path)
{
Filter = fileName,
EnableRaisingEvents = true
},
fsw =>
{
return Observable
.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
h => fsw.Changed += h, h => fsw.Changed -= h)
.Select(x => Unit.Default);
});
// Now we open a new stream on the same file, shift it to the same position as our previous one
// finished at, so we can continue with live updates
var messages =
Observable.Using(
() => new FileStream(logFileLocation, FileMode.Open, FileAccess.Read, FileShare.ReadWrite),
fs =>
{
fs.Seek(_fileStream.Position, SeekOrigin.Begin);
return Observable.Using(() => new StreamReader(fs),
sr =>
fileSystemWatcherChanges
.StartWith(Unit.Default)
.Select(x =>
Observable
.Defer(() => Observable.FromAsync(sr.ReadLineAsync))
.Repeat()
.TakeUntil(w => w == null))
.Merge()
.Where(w => w != null))
.Select((x, n) => new LogTailMessage(n, x));
});
_logger.Info($"Started tailing log file for {logFileLocation}");
Stream = messages
.Buffer(TimeSpan.FromMilliseconds(500), 100)
.Replay()
.RefCount();