[英]How I can inform unlocked thread (Monitor.Wait(), PulseAll() analog)
[英]How can I watch for newly created files and wait for them to be unlocked?
首先是手表方法; 我需要监视所有新创建的jpg文件,因为我尚不知道文件名。 我的程序每次在TextBox指定的目录中创建一个新的jpg。 因此,我的第一个问题是创建文件时如何知道/获取文件名?
第二个问题,我该如何使用所有这些方法,这两种方法以及更改的事件(下面的代码)? 单击按钮时会发生按钮单击事件,它将创建新的jpg文件。 然后在按钮单击事件中,我想开始观看它,并在标签上显示一条消息,例如:“正在创建文件等待”,然后在创建文件并准备使用时创建“文件已创建”。
private void watch()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = SavePathTextBox.Text;
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Filter = "*.jpg";
watcher.Changed += watcher_Changed;
watcher.EnableRaisingEvents = true;
}
然后是事件watcher_Changed
:
void watcher_Changed(object sender, FileSystemEventArgs e)
{
}
以及检查文件是否被锁定的方法
public static bool IsFileReady(String sFilename)
{
// If the file can be opened for exclusive access it means that the file
// is no longer locked by another process.
try
{
using (FileStream inputStream = File.Open(sFilename, FileMode.Open, FileAccess.Read, FileShare.None))
{
if (inputStream.Length > 0)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception)
{
return false;
}
}
这是我尝试的:
在按钮单击事件中:
private void TakePhotoButton_Click(object sender, EventArgs e)
{
try
{
if ((string)TvCoBox.SelectedItem == "Bulb") CameraHandler.TakePhoto((uint)BulbUpDo.Value);
else CameraHandler.TakePhoto();
watch();
}
catch (Exception ex) { ReportError(ex.Message, false); }
}
在watch方法中:
private void watch()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = SavePathTextBox.Text;
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Filter = "*.JPG";
watcher.Changed += watcher_Changed;
watcher.EnableRaisingEvents = true;
}
事件watcher_Changed
void watcher_Changed(object sender, FileSystemEventArgs e)
{
if (IsFileReady(e.FullPath) == false)
{
this.Invoke((Action)delegate { label6.Text = "Busy"; });
}
else
{
this.Invoke((Action)delegate { label6.Text = "File Ready"; });
}
}
以及查找文件是否被锁定的方法:
public static bool IsFileReady(String sFilename)
{
// If the file can be opened for exclusive access it means that the file
// is no longer locked by another process.
try
{
using (FileStream inputStream = File.Open(sFilename, FileMode.Open, FileAccess.Read, FileShare.None))
{
if (inputStream.Length > 0)
{
return true;
}
else
{
return false;
}
}
}
catch (Exception)
{
return false;
}
}
问题是,有时在大多数情况下,它会进入watcher_Changed事件内部的行:
this.Invoke((Action)delegate { label6.Text = "File Ready"; });
并使该行连续两次或有时甚至3次。 我可以说每次单击相机都会拍摄一张照片,它会创建两个文件,例如,一个文件名为IMG_0001.CR2,而一个Jpg文件则是IMG_0001.JPG
但是我不确定这是否就是为什么要去参加比赛,然后再做一次比赛。
我还检查了e.FullPath中的文件始终为.jpg而不是cr2。 问题是,为什么它到达那里再一次,我如何确保文件真的准备好了? (“文件就绪”)
也许我需要某种方式来跟踪文件大小,从0kb直到大小不再变化,然后再决定是否准备就绪?
我发现您使用观察器的方式存在一些问题。
CameraHandler.TakePhoto
应在调用CameraHandler.TakePhoto
之前运行,否则您将有机会错过。 TakePhotoButton_Click
上创建监视程序的新实例,也不要停止旧的实例。 否则,您每次点击都会获得一个新的正在运行的监视程序,并与您拥有的监视程序一样多地调用watcher_Changed
。 您现在正在等待的是写一些.jpg文件的结尾。 这可以满足您的需要,在这种情况下就很好。 但是,如果要等待文件创建,则需要其他设置。 这对我有用:
string watchDir = Application.StartupPath;
watcher = new FileSystemWatcher(watchDir, "*.jpg");
watcher.NotifyFilter |= NotifyFilters.Size;
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.EnableRaisingEvents = true;
protected void watcher_Created(object sender, FileSystemEventArgs e)
{
string changeType = e.ChangeType.ToString();
if (changeType != "Created")
{
return;
}
// file is created, wait for IsFileReady or whatever You need
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.