System.IO.IOException:’进程无法访问文件’@ .txt’,因为它正被另一个进程使用。

我是编程新手,我有一个问题。 如果我有两个函数,一个创建一个文本文件并写入其中,而另一个打开相同的文本文件并从中读取。

我得到的错误是:

System.IO.IOException:’进程无法访问文件’@ .txt’,因为它正被另一个进程使用。

我已经尝试为每个function设置单独的计时器,但它仍然无效。 我认为最好的方法是函数2在函数1结束之前不会启动。

你能帮助我实现这个目标吗? 非常感谢你! 麦克风

源代码:

public Form1() { InitializeComponent(); System.Timers.Timer timerButtona1 = new System.Timers.Timer(); timerButtona1.Elapsed += new ElapsedEventHandler(tickTimera1); timerButtona1.Interval = 3003; timerButtona1.Enabled = true; } private async void tickTimera1(object source, ElapsedEventArgs e) { function1(); function2(); } void function1() { List linki = new List(); linki.Add("https://link1.net/"); linki.Add("https://link2.net/"); linki.Add("https://link3.net/"); List fileNames = new List(); fileNames.Add("name1"); fileNames.Add("name2"); fileNames.Add("name3"); for (int x = 0; x < fileNames.Count; x++) { GET(linki[x], fileNames[x]); //System.Threading.Thread.Sleep(6000); } } async void GET(string link, string fileName) { var ODGOVOR = await PRENOS_PODATKOV.GetStringAsync(link); File.WriteAllText(@"C:\Users\...\" + fileName + ".txt", ODGOVOR); } void function2() { string originalText = File.ReadAllText(@"C:\Users\...\fileName.txt", Encoding.Default); dynamic modifiedText = JsonConvert.DeserializeObject(originalText); //then i then i read from the same text files and use some data from it.. } 

编辑后,您必须关闭该文件。

 var myFile = File.Create(myPath); //myPath = "C:\file.txt" myFile.Close(); //closes the text file for eg. file.txt //You can write your reading functions now.. 

关闭后你可以再次使用它(用于阅读)

在写完文本文件后,您应先关闭它,然后再继续执行第二个function:

 var myFile = File.Create(myPath); //some other operations here like writing into the text file myFile.Close(); //close text file //call your 2nd function here 

只是详细说明:

 public void Start() { string filename = "myFile.txt"; CreateFile(filename); //call your create textfile method ReadFile(filename); //call read file method } public void CreateFile(string filename) { var myFile = File.Create(myPath); //create file //some other operations here like writing into the text file myFile.Close(); //close text file } public void ReadFile(string filename) { string text; var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read); //open text file //vvv read text file (or however you implement it like here vvv using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) { text = streamReader.ReadToEnd(); } //finally, close text file fileStream.Close(); } 

关键是,在完成对文件的任何操作后,必须关闭FileStream。 你可以通过myFileStream.Close()来做到这一点。

此外, File.Create(filename)返回一个FileStream对象,然后可以Close()

实际上这不是关闭/处理流的问题, File.WriteAllTextFile.ReadAllText在内部执行此操作。

问题是因为错误使用async/await模式。 GET是异步但从未等待过,因此导致function1完成并在所有内容实际写入文件之前转移到function2

写它的方式GET是不可接受的,因为它是async void ,除非你处理事件或者真的知道你在做什么,否则永远不应该使用它。

因此,要么完全删除async/await的使用,要么一直是async

  1. 改变GET是等待的:

     async Task GET(string link, string fileName) 
  2. 在现在的async function1等待它:

     async Task function1() { ... for (int x = 0; x < fileNames.Count; x++) { await GET(linki[x], fileNames[x]); //System.Threading.Thread.Sleep(6000); } ... 
  3. 等待Elapsed事件中的function1

     private async void tickTimera1(object source, ElapsedEventArgs e) { await function1(); function2(); } 

问题是有时文件锁在关闭后不会立即释放。

您可以尝试运行循环来读取文件。 在循环内部放置一个try catch语句,如果文件读取成功则从循环中断开。 否则,请等待几毫秒并尝试再次读取该文件:

 string originalText = null; while (true) { try { originalText = File.ReadAllText(@"C:\Users\...\fileName.txt", Encoding.Default); break; } catch { System.Threading.Thread.Sleep(100); } }