手动重置事件将阻止我的所有线程或仅阻止我的对象线程

本文关键字:我的 线程 对象 事件 | 更新日期: 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)之类的东西。这些可能会产生不可预测的结果。