FileSystemWatcher触发Created事件时PictureBox无法显示新图的问题咨询
解决FileSystemWatcher触发Created时PictureBox无法显示图片的问题
哎,这个坑我之前踩过!核心原因其实很简单:FileSystemWatcher的Created事件触发得太早了。当Created事件触发时,文件只是刚被创建出来,但大概率还在被写入数据(比如有些程序生成图片时,会先创建空文件,再逐步写入内容),这时候你直接读取图片流,拿到的是不完整的文件,PictureBox自然加载失败。而复制粘贴是一次性把整个文件内容写完才触发事件,所以能正常显示。
下面给你几个亲测有效的解决步骤:
1. 等待文件完全写入(释放锁)
在读取图片前,必须确保文件已经写完且没被其他进程锁定。可以写个辅助方法循环检查文件是否可用:
private bool IsFileReady(string filePath) { try { using (var stream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { return stream.Length > 0; } } catch (IOException) { // 文件被锁定,还没写完 return false; } }
在Created事件里调用这个方法,等待文件就绪:
private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e) { // 最多等待5秒(可按需调整) int waitCount = 0; while (!IsFileReady(e.FullPath) && waitCount < 50) { Thread.Sleep(100); waitCount++; } if (waitCount >= 50) { // 超时处理,比如记录日志 return; } // 加载图片到PictureBox LoadPictureToBox(e.FullPath); }
2. 线程安全更新UI
FileSystemWatcher的事件是在后台线程触发的,直接更新PictureBox会触发跨线程异常,必须切换到UI线程操作:
private void LoadPictureToBox(string filePath) { if (pictureBox1.InvokeRequired) { pictureBox1.Invoke(new Action<string>(LoadPictureToBox), filePath); return; } // 用MemoryStream加载,避免占用文件锁 try { using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) using (var ms = new MemoryStream()) { fs.CopyTo(ms); ms.Position = 0; pictureBox1.Image = Image.FromStream(ms); } } catch (Exception ex) { // 异常处理,比如显示默认图片 pictureBox1.Image = Properties.Resources.DefaultImage; } }
用MemoryStream是因为直接用FileStream会保持文件锁定,可能影响后续操作,把内容读到内存里就没这个问题了。
3. 额外优化建议
- 可以同时监听Changed事件作为补充,有些场景下Created事件可能没捕捉到,但Changed会在文件内容更新后触发;
- 记得过滤非JPG文件,避免无效加载。
按照上面的步骤调整代码,应该就能解决你的问题了!
内容的提问来源于stack exchange,提问作者Eric Kung
相关产品推荐
相关产品推荐

