ManualResetEvent会阻止我的所有线程还是只阻止我的对象线程?

时间:2013-10-14 13:36:44

标签: c# multithreading winforms

我有一个承载winform服务的WCF应用程序。

此应用程序支持多个客户端,每个客户端向我的应用程序发送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
}

所以我的问题是,这个解决方案是否只会阻止当前线程或所有客户端线程?

2 个答案:

答案 0 :(得分:0)

它只会阻止当前线程。如果它会阻塞所有线程,就没有线程能够调用mre.Set()

如果你想要的只是等待(mre.Set()没有在任何地方调用过),你可以改用Thread.Sleep(2000);

答案 1 :(得分:0)

我觉得你的方法存在一些问题......

首先,听起来你在游泳条件下游泳......添加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)之类的东西。这些可能会产生不可预测的结果。