在while循环期间文件正在被另一个进程使用(C#)

3

我目前有一个包含if语句的while循环:

if (s.Contains("mp4:production/CATCHUP/"))

尽管条件为真,当我尝试使用其他方法(如下所示的RemoveEXELog)时,我会收到“拒绝访问”的错误,因为进程正在使用文件“Command.bat”。

我该如何停止循环执行文件并运行其他方法?

private void CheckLog()
{
    while (true)
    {
        Thread.Sleep(5000);
        if (!System.IO.File.Exists("Command.bat")) continue;
        using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
        {
            string s = "";
            while ((s = sr.ReadLine()) != null)
            {
                if (s.Contains("mp4:production/CATCHUP/"))
                {

                    RemoveEXELog(); // Deletes a specific keyword from Command.bat

                    Process p = new Process();
                    p.StartInfo.WorkingDirectory = "dump";
                    p.StartInfo.FileName = "test.exe";
                    p.StartInfo.Arguments = s;
                    p.Start();

                    ClearLog(); // Deletes Command.bat and then creates a new empty Command.bat
                }
            }
        }
    }
}

“那个‘其他进程’就是你。使用File.ReadAllText()读取文件内容,操作字符串,然后使用File.WriteAllText()写入文件。” - Hans Passant
你需要执行多个异步操作还是只有一个?你只需要查找一个“mp4:production / CATCHUP /”实例还是多个? - Sean Thoman
你一直在问关于这个的问题。 - Jesus Ramos
3个回答

3
其他解决方案对您应该有效,但您还可以这样打开文件:
using (var sr = new FileStream("Command.bat", FileMode.Open, 
                               FileAccess.Read, FileShare.ReadWrite))
{
    ...
}

这将以只读模式打开文件。

然后在您的RemoveEXELog()方法中,您可以这样打开它:

using (var sr = new FileStream("Command.bat", FileMode.Open, 
                               FileAccess.ReadWrite, FileShare.ReadWrite))
{
    ...
}

这种方法可以让您在不出现文件已被使用的I/O异常的情况下从两个位置打开文件。

1
private void CheckLog()
    {
        bool _found;
        while (true)
        {
            string s = "";
            _found = false;
            Thread.Sleep(5000);
            if (!System.IO.File.Exists("Command.bat")) continue;
            using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
            {
                while ((s = sr.ReadLine()) != null)
                {
                    if (s.Contains("mp4:production/CATCHUP/"))
                    {
                       _found = true;
                       break;
                    }

                }
            }
            if (_found)
            {
                 RemoveEXELog(); // Deletes a specific keyword from Command.bat

                 Process p = new Process();
                 p.StartInfo.WorkingDirectory = "dump";
                 p.StartInfo.FileName = "test.exe";
                 p.StartInfo.Arguments = s;
                 p.Start();

                 ClearLog(); // Deletes Command.bat and then creates a new empty Command.bat
            }
        }
    }

@Marino Šimić 这个几乎可以用... 我唯一遇到的问题是:当前上下文中不存在 's' 这个名字 - p.StartInfo.Arguments = s; - James

0

我理解你的代码中这几行是正确的:

RemoveEXELog(); // Deletes a specific keyword from Command.bat
ClearLog(); /

你正在处理 Command.bat 文件吗? 如果是的话,你必须将它们移出来。

using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))

block,因为这个读取器防止其他程序编辑文件。

尝试使用一些布尔标志:

bool needRemove = false, needClear = false;
using (System.IO.StreamReader sr = System.IO.File.OpenText("Command.bat"))
{
    string s = "";
    while ((s = sr.ReadLine()) != null)
    {
        if (s.Contains("mp4:production/CATCHUP/"))
        {
            needRemove = true;

            Process p = new Process();
            p.StartInfo.WorkingDirectory = "dump";
            p.StartInfo.FileName = "test.exe";
            p.StartInfo.Arguments = s;
            p.Start();

            needClear = true;
        }
    }
}

if (needRemove) RemoveEXELog(); // Deletes a specific keyword from Command.bat
if (needClear) ClearLog(); // Deletes Command.bat and then creates a new empty Command.bat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接