0

我有一个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
}

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

4

2 回答 2

0

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

如果您只想等待(mre.Set()不在任何地方调用),则可以Thread.Sleep(2000);改用。

于 2013-10-14T13:52:38.420 回答
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). 这些可能会产生不可预测的结果。

于 2013-10-14T15:17:17.353 回答