简体   繁体   中英

FileSystemWatcher cannot access file because its being used by another process

Here my situation. I'm still pretty new at this. I'm generating some .txt files in my linux virtual box and using ac# winform application in windows to load the data into a chart. There are around 20 files or so. What I need to happen is to load the first file, display it on the chart, reload the file and display it on the chart, reload the file, display it on the chart, etc. My c code is writing over the same file every time with new values. So in the winforms when you are looking at the chart you will kind of see the data transforming as each new dataset is loaded. This should happen fairly quickly. Some of the new data loads but then I get the error about the file being used by another process. I've been reading about the error but I guess I still don't understand how to fix it. I need my c code that is generating the files to line up with the c# chart loading code so that it happens smoothly. In CI am also getting an error message that the file couldn't be opened for writing.

Here is what I'e tried so far. I tried waiting for a moment in the c code before opening the file for writing which didn't work. I've also tried just trying to open the file repeatedly until it opens without error, but it didn't work. My only other solution I could think of was to just create files like 1.txt 2.txt 3.txt... and then load them in succession. That might be the way I have to go. But I'm still new and don't actually know if I'm doing this the best way to start.

C code

for(i = 0; i < FILES; i++){
    fd = fopen(path, "w+");
    if( fd == NULL ){
        printf( "Could not open file for writing. Exiting...\n");
        exit(-1);
    }
    for(j = 0; j < ROW; j++){
        fprintf(fd, "%.4f", vector[i][j]);
        fprintf(fd, "%s", "\n");
    }
    fclose(fd);
}   

C# Code

// Define the event handlers. 
private void OnChanged(object source, FileSystemEventArgs e)
{
    FinalList.Clear();
    chart4.Series[0].Points.Clear();
    loadData(FinalPath, FinalList, chart4);
 }

private void loadData(String path, List<double> list, System.Windows.Forms.DataVisualization.Charting.Chart chart)
{
    string line = null;
    double value = 0;        
    using (TextReader reader = File.OpenText(path))
    {
        line = reader.ReadLine();
        while (line != null)
        {
                value = System.Convert.ToDouble(line);
                list.Add(value);
                line = reader.ReadLine();
            }
        }

        for (int i = 0; i < ROW; i++)
        {
            chart.Series["Graph"].Points.AddXY(i + 1, list[i]);

        }
    }

I guess using a (network?) filesystem is a bad way to do inter-process communication between different platforms. You will have synchronization problems if you continue this way. Just imagine the the moment file is only half-written by the C-code. Because of a full buffer, the Linux system might sync this file to disk. Now your windows C# application reads the file, but will only get half of it. This is not what you want, because your c# application will never know when the C program is done with writing the complete file.

I suggest you use a socket to transport the data between Linux and Windows.


On the linux side, you could you could use a very very cheap socket implementation. You could write your data to eg, file.txt and use the system command in conjunction with netcat ( nc on ubuntu) to publish the file.

cat file.txt | nc -l 1234

I seems like you can also download netcat for windows. You can fetch your file like this (replace 1.2.3.4 with the ip address of your Linux VM):

nc 1.2.3.4 1234 > file.txt

Make sure your windows can reach the Linux VM. With the VirtualBox default network mode (NAT), this is not possible, but you can easily change it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM