Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 并发文件访问_C#_Winforms - Fatal编程技术网

C# 并发文件访问

C# 并发文件访问,c#,winforms,C#,Winforms,我正在运行一个应用程序的多个实例,该应用程序从文件中读取第一行,然后删除第一行并以相同的名称保存文件。我发现在某些情况下,应用程序会崩溃。我创建了一个示例程序,只是为了更好地理解我遇到的问题。 如果我运行这个程序的四个实例,有时多个实例会试图删除同一行。最后操作成功了,但效率不高。如何改进代码以避免这种情况?也许每个实例在使用文件时都需要锁定该文件 using System; using System.Collections.Generic; using System.Drawing; usin

我正在运行一个应用程序的多个实例,该应用程序从文件中读取第一行,然后删除第一行并以相同的名称保存文件。我发现在某些情况下,应用程序会崩溃。我创建了一个示例程序,只是为了更好地理解我遇到的问题。 如果我运行这个程序的四个实例,有时多个实例会试图删除同一行。最后操作成功了,但效率不高。如何改进代码以避免这种情况?也许每个实例在使用文件时都需要锁定该文件

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace ConcurrentFileAccess
{
    public partial class MainForm : Form
    {
        bool gbAbort = false;
        public MainForm()
        {
            InitializeComponent();
        }

        void BtnCreateFileClick(object sender, EventArgs e)
        {
            string sFile = @"S:\Temp\concurrentFileAccess.txt";
            Stopwatch stopwatch = Stopwatch.StartNew();
            if (File.Exists(sFile)) {
                File.Delete(sFile);
            }

            if (!File.Exists(sFile)) {
                List<string> list = new List<string>();
                var fc = File.Create(sFile);
                fc.Close();
                for (int i = 1; i <= 200; i++) {
                    list.Add(i.ToString());
                }

                File.WriteAllLines(sFile, list);
                listBox1.Items.Add("File " + sFile + " was created and it contains 200 lines");
            } else {
                string[] lines = File.ReadAllLines(sFile);
                int nlines = lines.Length;
                listBox1.Items.Add("File " + sFile + " already exists and it contains " + nlines + " lines");
            }

            stopwatch.Stop();
            listBox1.Items.Add("File created in " + stopwatch.Elapsed.ToString("hh\\:mm\\:ss\\.fff"));          
        }

        void BtnDeleteFromFileClick(object sender, EventArgs e)
        {
            gbAbort = false;
            int nlines = 9999;
            while (nlines > 0) {
                nlines = DeleteOneLine();
                Application.DoEvents();
                if (gbAbort) {
                    return;
                }
            }
        }

        int DeleteOneLine()
        {
            string sFile = @"S:\Temp\concurrentFileAccess.txt";
            listBox1.Items.Add("We are in DeleteLines()...");
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            Application.DoEvents();

            int nLinesLeft = 9999;
            string line0 = string.Empty;
            Stopwatch stopwatch = Stopwatch.StartNew();
            int ntry = 0;
            while (ntry < 100) {
                try {
                    string[] lines = File.ReadAllLines(sFile);
                    List<string> list = new List<string>(lines);
                    nLinesLeft = list.Count;
                    if (nLinesLeft > 0) {
                        line0 = list[0];
                        list.RemoveAt(0);
                        listBox1.Items.Add("Deleted line " + line0);
                        listBox1.SelectedIndex = listBox1.Items.Count - 1;
                        Application.DoEvents();
                        listBox1.Items.Add("Writing to file after line " + line0 + " was deleted");
                        File.WriteAllLines(sFile, list);
                        nLinesLeft = list.Count;
                        Application.DoEvents();
                    } else {
                        nLinesLeft = 0;
                        break;
                    }
                } catch (Exception) {
                    ntry++;
                    listBox1.Items.Add("ntry = " + ntry + ", could not delete line " + line0 + " from file. Attempting again...");
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;
                    Application.DoEvents();
                    Application.DoEvents();
                    Thread.Sleep(50);
                }
            }

            if(ntry >= 100) {
                nLinesLeft = -1; // should never get here
            }

            stopwatch.Stop();
            listBox1.Items.Add("ntry: " + ntry + ", lines Left: " + nLinesLeft + ", elapsed = " + stopwatch.Elapsed.ToString("hh\\:mm\\:ss\\.fff"));
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            Application.DoEvents();
            return nLinesLeft;
        }

        void BtnAbortClick(object sender, EventArgs e)
        {
            gbAbort = true;
        }

        void BtnOpenAppFolderClick(object sender, EventArgs e)
        {
            string sFile = Application.ExecutablePath;
            string sPath = Path.GetDirectoryName(sFile);
            Process.Start(sPath);
        }

        void BtnOpenFileClick(object sender, EventArgs e)
        {
            string sFile = @"S:\Temp\concurrentFileAccess.txt"; 
            if(File.Exists(sFile)) {
                Process.Start(sFile);
            }
            else {
                MessageBox.Show("File " + sFile + " not found");
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统图;
使用System.Windows.Forms;
使用System.IO;
使用系统线程;
使用系统诊断;
命名空间ConcurrentFileAccess
{
公共部分类主窗体:窗体
{
bool-gbAbort=false;
公共表格(
{
初始化组件();
}
void BtnCreateFileClick(对象发送者,事件参数e)
{
字符串sFile=@“S:\Temp\concurrentFileAccess.txt”;
秒表秒表=Stopwatch.StartNew();
if(File.Exists(sFile)){
文件删除(sFile);
}
如果(!File.Exists(sFile)){
列表=新列表();
var fc=File.Create(sFile);
fc.Close();
对于(int i=1;i 0){
nlines=DeleteOneLine();
Application.DoEvents();
伊夫(巴博尔特){
返回;
}
}
}
int DeleteOneLine()
{
字符串sFile=@“S:\Temp\concurrentFileAccess.txt”;
listBox1.Items.Add(“我们在DeleteLines()…”;
listBox1.SelectedIndex=listBox1.Items.Count-1;
Application.DoEvents();
int nLinesLeft=9999;
string line0=string.Empty;
秒表秒表=Stopwatch.StartNew();
intntry=0;
而(ntry<100){
试一试{
string[]lines=File.ReadAllLines(sFile);
列表=新列表(行);
nLinesLeft=list.Count;
如果(nLinesLeft>0){
line0=列表[0];
移除列表(0);
listBox1.Items.Add(“删除行”+line0);
listBox1.SelectedIndex=listBox1.Items.Count-1;
Application.DoEvents();
listBox1.Items.Add(“删除第“+line0+”行后写入文件”);
File.writeAllines(sFile,list);
nLinesLeft=list.Count;
Application.DoEvents();
}否则{
nLinesLeft=0;
打破
}
}捕获(例外){
ntry++;
listBox1.Items.Add(“ntry=“+ntry+”,无法从文件中删除行“+line0+”。再次尝试…”);
listBox1.SelectedIndex=listBox1.Items.Count-1;
Application.DoEvents();
Application.DoEvents();
睡眠(50);
}
}
如果(ntry>=100){
nLinesLeft=-1;//不应该到这里
}
秒表;
列表框1.Items.Add(“ntry:+ntry+”,左行:“+nLinesLeft+”,已用=“+stopwatch.appeased.ToString”(“hh\\\:mm\\:ss\\\.fff”);
listBox1.SelectedIndex=listBox1.Items.Count-1;
Application.DoEvents();
返回nLinesLeft;
}
void BtnAbortClick(对象发送方,事件参数e)
{
gbAbort=true;
}
void BtnOpenAppFolderClick(对象发送方,事件参数e)
{
字符串sFile=Application.ExecutablePath;
string sPath=Path.GetDirectoryName(sFile);
过程启动(sPath);
}
void BtnOpenFileClick(对象发送方,事件参数e)
{
字符串sFile=@“S:\Temp\concurrentFileAccess.txt”;
if(File.Exists(sFile)){
进程启动(sFile);
}
否则{
Show(“文件”+sFile+“未找到”);
}
}
}
}

您可以使用a来实现。谢谢,这似乎是个好主意。我将尝试实现它。