C# .NET BackgroundWorker 6 FileSystemWatcher进程无法访问文件“PATH”,因为它正被另一个进程使用

tvz2xvvm  于 2022-12-30  发布在  .NET
关注(0)|答案(1)|浏览(158)

我尝试观察以.csv结尾的新添加文件的目录,删除文件并等待新添加的文件再次处理文件。我使用BackgroundService,代码如下:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly IProcessFileService _processFileService;
    private ApplicationOptions _applicationOptions;
    private FileSystemWatcher _watcher = new();

    public Worker(ILogger<Worker> logger, IProcessFileService processFileService, IOptions<ApplicationOptions> applicationOptions)
    {
        _logger = logger;
        _processFileService = processFileService;
        _applicationOptions = applicationOptions.Value;
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        string filePath = _applicationOptions.InputDirectory;
        _watcher.Path = filePath;
        _watcher.EnableRaisingEvents = true;
        _watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastWrite;
        _watcher.Filter = "*.csv*";
        _watcher.Created += new FileSystemEventHandler(OnFileCreated);
        return Task.CompletedTask;
    }

    private async void OnFileCreated(object sender, FileSystemEventArgs e)
    {
        if (e.ChangeType == WatcherChangeTypes.Created)
        {
            await HandleAddedFile();
        }     
    }

    private async Task HandleAddedFile()
    {
        try
        {
           await _processFileService.ProcessFile();
        }
        catch(Exception ex)
        {
            _logger.LogError("{error}", ex.Message);
        }
       _processFileService.DeleteFileAndLog();
    }
}

第一次工作正常,但当尝试在目录中插入第二个文件时,我得到错误:进程无法访问文件“PATH”,因为另一个进程正在使用它。
处理标签包括一些异步工作,我如何解决这个问题?

prdp8dxp

prdp8dxp1#

我一直沿着罗伯特给我的线索走我不得不重写一些东西,但是我现在已经使用下面的代码使它工作了。我还不得不修改一些函数以接受完整路径。

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly IProcessFileService _processFileService;
    private ApplicationOptions _applicationOptions;
    private FileSystemWatcher _watcher = new();

    public Worker(ILogger<Worker> logger, IProcessFileService processFileService, IOptions<ApplicationOptions> applicationOptions)
    {
        _logger = logger;
        _processFileService = processFileService;
        _applicationOptions = applicationOptions.Value;
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        string filePath = _applicationOptions.InputDirectory;
        _watcher.Path = filePath;
        _watcher.EnableRaisingEvents = true;
        _watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastWrite;
        _watcher.Filter = "*.csv*";
        _watcher.Created += new FileSystemEventHandler(OnFileCreated);
        return Task.CompletedTask;
    }

    private async void OnFileCreated(object sender, FileSystemEventArgs e)
    {
        if (e.ChangeType == WatcherChangeTypes.Created)
        {
            await HandleAddedFile(e);
        }     
    }

    static FileStream? WaitForFile(string fullPath, FileMode mode, FileAccess access, FileShare share)
    {
        for (int numTries = 0; numTries < 10; numTries++)
        {
            FileStream? fs = null;
            try
            {
                fs = new FileStream(fullPath, mode, access, share);
                return fs;
            }
            catch (IOException)
            {
                fs?.Dispose();
                Thread.Sleep(50);
            }
        }

        return null;
    }

    private async Task HandleAddedFile(FileSystemEventArgs e)
    {
        FileStream? fileStream = null;
        try
        {
           fileStream = WaitForFile(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
           await _processFileService.ProcessFile(e.FullPath);
        }
        catch(Exception ex)
        {
            _logger.LogError("{error}", ex.Message);
        }
        fileStream?.Dispose();
       _processFileService.DeleteFileAndLog(e.FullPath);
    }
}

相关问题