-2

in my code I am doing an iterate calculation which looks as follows:

/// the iteration calculation function
private void DoCalculationEx(string targetFileSource, int num) {
    //first, kill the process TrustMoment.exe if it exists
    foreach (var process in Process.GetProcessesByName("TrustMoment"))
            {
                process.Kill();
            }
    //Then, write contents to the file using a streamwriter
    ExportFile(targetFileSource);
    
    //call the process TrustMoment.exe which uses the file
    Process pro = new Process();
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.FileName = "TrustMoment.exe";
    startInfo.WorkingDirectory = targetDirectory;
    pro.StartInfo = startInfo;
    pro.Start();
    pro.WaitForExit(5000);  

    //to make sure the process ends, I even sleep the thread
    Thread.Sleep(1000);

    ...
    doing other things
}

As in my code, the file is firstly written content, then I will call an exterior exe ( TrustMoment.exe) which will read the contents in the file. during the 1st iteration, the code runs ok, but when it comes to 2nd iteration, I will get error message that The file is used by another process. I am pretty sure that this file is used by TrustMoment.exe so I tried to kill TrustMoment.exe before I write contents into the file. But still I got the error message.

As I cannot see which process used it, I am unsure how to solve this problem. Can anyone help me solving this issue? (maybe by async and await, but I am not familiar with it).

By the way when I add some breakpoint in code, it works ok.

Function ExportFile looks as follows:

        private void ExportFile(string targetFileSource)
        {

            StreamWriter sr = new StreamWriter(targetFileSource);

            //basic info
            sr.WriteLine(this.sliceNum.ToString() + " " + this.earthquakeRatio.ToString());

            //coordinate
            for (int i = this.sliceNum; i >= 0; i--)
            {
                string s0 = string.Format("{0:0.0000}", this.topPoints[i].X);
                string s1 = string.Format("{0:0.0000}", this.topPoints[i].Y);
                string s2 = string.Format("{0:0.0000}", this.bottomPoints[i].X);
                string s3 = string.Format("{0:0.0000}", this.bottomPoints[i].Y);
                string s4 = string.Format("{0:0.0000}", this.waterLevelPoints[i].X);
                string s5 = string.Format("{0:0.0000}", this.waterLevelPoints[i].Y > this.bottomPoints[i].Y ? waterLevelPoints[i].Y : bottomPoints[i].Y);



                //string coordinateStr = string.Join("\t", this.topPoints[i].X, this.topPoints[i].Y,
                //    this.bottomPoints[i].X, this.bottomPoints[i].Y, this.waterLevelPoints[i].X,
                //    this.waterLevelPoints[i].Y);
                string coordinateStr = string.Join("\t", s0, s1, s2, s3, s4, s5);
                sr.WriteLine(coordinateStr);
            }

            //material
            for (int i = this.sliceNum - 1; i >= 0; i--)
            {
                //save fi in radian
                double fi = Math.Tan((Math.PI / 180) * phiArr[i]);
                string sf = string.Format("{0:0.0000}", fi);

                string matStr = string.Join("\t", sf, this.cArr[i],
                    this.naturalDensityArr[i], this.satDensityArr[i], this.pphArr[i], this.ppvArr[i]);
                sr.WriteLine(matStr);
            }

            //magicNumber 0.918
            sr.WriteLine("0.918");
            sr.Close();
        }
Lake_Lagunita
  • 521
  • 1
  • 4
  • 20
  • Show us `ExportFile`. – mjwills May 26 '21 at 06:44
  • @mjwills I have posted ExportFile. Thank you so much. – Lake_Lagunita May 26 '21 at 06:55
  • 1
    Try and use `using StreamWriter ...` - probably won't solve your problem, but will make the app more stable. (disposes of the streamwriter properly) See https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement – Fildor May 26 '21 at 07:16
  • @Fildor tried using StreamWriter but still has the same problem. – Lake_Lagunita May 26 '21 at 07:49
  • You were using one before. I suggested [`using`](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement). Also, if you close a file and try to open it right away, it even may hiccup if it's the _same_ process on some FileSystems. So it's extremely important to make sure, all resources that use the file are closed and disposed as early as possible. But of course, there might be some dangling filehandle in `TrustMoment.exe`. – Fildor May 26 '21 at 07:54
  • Is File I/O the only option you have for communication with "TrustMoment.exe" ? – Fildor May 26 '21 at 07:55
  • By the way [`public bool WaitForExit (int milliseconds);`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexit?view=net-5.0#System_Diagnostics_Process_WaitForExit_System_Int32_) only waits 5 seconds in your code. You need to check its result to make sure it actually exited. If it didn't then you are only **guessing** it needs one more second ... I think this is the place to start improvement. – Fildor May 26 '21 at 07:59
  • Also, what does "TrustMoment" actually do and what does it mean to kill it? Don't you destabilize the overall Software / Process by just shooting it in the head potentially amidst processing the file (maybe causing dangling file handles that aren't closed properly .... )? – Fildor May 26 '21 at 08:01
  • @Fildor I guess the most possible error happens in the TrustMoment.exe. Actually this is an executable from a professor. Sadly the source code is not accessible now. But I am now pretty sure it is the issue. – Lake_Lagunita May 26 '21 at 08:15
  • @Fildor actually this is a co-operate project between our company and the professor. Just at beginning I just try to use the exe file to check if the calculation is good. – Lake_Lagunita May 26 '21 at 08:17
  • Just a piece of advice: Do not go to your professor and blatantly tell him, he's got a bug in his code. If you seek his help maybe suggest _you may be using his app wrong_. ;D – Fildor May 26 '21 at 08:17
  • And maybe you can agree on something more reliable than File I/O ... That's ok for a quick and dirty Mockup. But if you want to go for something more reliable, don't depend on the FileSystem. – Fildor May 26 '21 at 08:21
  • @Fildor yes. Thanks for your advice. Next step maybe we will use dll instead of exe. – Lake_Lagunita May 26 '21 at 08:37
  • @Fildor just got the source code... It is written in Fortran. I just browsed the code, the file was closed correctly. Maybe my guess is wrong. The problem still lies in my code... – Lake_Lagunita May 26 '21 at 08:57
  • @Fildor, just solved the problem. Don't know how, but it succeeded. – Lake_Lagunita May 26 '21 at 09:51

1 Answers1

0

I found a solution from this: How do I find out which process is locking a file using .NET? (refer to the 2nd answer)

by using the class FileUtil, I successfully solved the issue:

enter image description here

BTW, as you can see, I am really interested in which process is using the file so I put the breakpoint into the else part. However, the breakpoint is never reached which means that no process uses the file. I dont know why but anyhow it solved my problem.

Lake_Lagunita
  • 521
  • 1
  • 4
  • 20