手动重置事件将阻止我的所有线程或仅阻止我的对象线程
本文关键字:我的 线程 对象 事件 | 更新日期: 2023-09-27 18:35:12
我有一个托管WCF
服务的winform
应用程序。
此应用程序支持多个客户端,每个客户端向我的应用程序发送一个表示文件名的string
。 我的申请开始处理并完成工作。进程结束后(每个进程在有限的时间内打开),我的进程将引发退出事件。
创建将文件复制到新位置的进程的文件,然后删除旧文件。此时,大多数情况都会失败,因为我的文件仍在使用中。所以我想知道如何处理这个问题。
这就是我打开流程的方式:
ProcessStartInfo tsharkStartInfo = new ProcessStartInfo();
Process pros = new Process();
tsharkStartInfo.FileName = processToInvoke;
tsharkStartInfo.RedirectStandardOutput = true;
tsharkStartInfo.RedirectStandardError = true;
tsharkStartInfo.RedirectStandardInput = true;
tsharkStartInfo.UseShellExecute = false;
tsharkStartInfo.CreateNoWindow = true;
tsharkStartInfo.Arguments = args;
pros.StartInfo = tsharkStartInfo;
pros.ErrorDataReceived += pros_ErrorDataReceived;
pros.OutputDataReceived += pros_OutputDataReceived;
pros.EnableRaisingEvents = true;
pros.Start();
pros.BeginOutputReadLine();
pros.BeginErrorReadLine();
pros.EnableRaisingEvents = true;
pros.Exited += (object sender, EventArgs e) =>
{
if (ProcessExitedEvent != null)
ProcessExitedEvent(pros.Id); // Raised this event when my process exit
};
private void processExitEvent()
{
// copy the file to new location
// delete the old file
}
所以我应该做这样的事情:
ManualResetEvent mre = new ManualResetEvent(false);
private void processExitEvent()
{
// copy the file to new location
mre.WaitOne(2000); // wait 2 seconds to ensure my file not longer in use
// delete the old file
}
所以我的问题是,此解决方案是仅阻止当前线程还是所有客户端线程?
它只会阻止当前线程。如果它会阻塞所有线程,则没有线程能够调用mre.Set()
!
如果您只想等待(mre.Set()
任何地方都没有调用),则可以改用Thread.Sleep(2000);
。
我觉得
你的方法有一些问题......
首先,听起来你在比赛条件下游泳......这次添加sleep(2000)
可能会修复它...但不是每次。 这绝对是错误的方法。 在继续之前,您要确保该文件将绝对关闭。 这意味着,应在引发event
之前关闭文件。
其次,听起来您正在尝试对尚未关闭的文件执行操作......
在 C# 中,始终避免这种情况的一个可靠方法是使用 using
块。
因此,假设您有这样的东西:
using (FileStream fs = File.OpenRead(x))
{
// Copy the file...
// End of scope - This will close the file.
}
// Raise exit event.
使用 using
语句的好处是,一旦您退出此块,您就可以确定......该文件将被关闭。
最终。。。您只想避免依赖诸如sleep(2000)
甚至WaitOne(2000)
之类的东西。这些可能会产生不可预测的结果。