问题
I have a text file installer_input.txt and a checkedListBox2 in a form application. I want to edit the text file if I have some changes in checkesListBox2. I have two parts of code, I know that are so long, but I need some help :
private void checkedListBox2_SelectedIndexChanged(object sender, EventArgs e)
{
string path = AppDomain.CurrentDomain.BaseDirectory.ToString();
var lin = (path + "config.ini").ToString();
var lines = File.ReadAllLines(lin);
string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile="))
.Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault();
string pathTemp = @"C:\temp\";
string[] pathArr = InstallerFile.Split('\\');
string[] fileArr = pathArr.Last().Split('\\');
string fileArr1 = String.Join(" ", fileArr);
string installerfilename = string.Format("{0}{1}", pathTemp, fileArr1);
IEnumerable<string> inilines = File.ReadAllLines(installerfilename).AsEnumerable();
bool IsChecked = checkedListBox2.CheckedItems.Contains(checkedListBox2.SelectedItem);
else if (fileArr1.Equals("installer_input.txt"))
{
if (IsChecked && checkedListBox2.CheckedItems.Count != checkedListBox2.Items.Count)
inilines = inilines.Select(line => line == string.Format("#product.{0}", checkedListBox2.SelectedItem)
? Regex.Replace(line, string.Format("#product.{0}", checkedListBox2.SelectedItem), string.Format(@"product.{0}", checkedListBox2.SelectedItem))
: line);
else if (!IsChecked || checkedListBox2.CheckedItems.Count == checkedListBox2.Items.Count)
inilines = inilines.Select(line => (line == string.Format("product.{0}", checkedListBox2.SelectedItem))
? Regex.Replace(line, string.Format(@".*product.{0}", checkedListBox2.SelectedItem), string.Format(@"#product.{0}", checkedListBox2.SelectedItem))
: line);
if (checkedListBox2.CheckedItems.Count == checkedListBox2.Items.Count)
checkBox1.Checked = true;
else
checkBox1.Checked = false;
string strWrite = string.Join(Environment.NewLine, inilines.ToArray());
File.WriteAllText(installerfilename, strWrite);
}
}
And the second code is :
private void checkBox1_CheckedChanged_1(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
SetAllItemsChecked(cb.Checked);
var installerLines = ReadInstallerLines();
SetAllProductsChecked(installerLines.ToList(), cb.Checked);
SaveInstaller(installerLines);
}
private void SetAllItemsChecked(bool check)
{
for (int i = 0; i < this.checkedListBox2.Items.Count; i++)
{
this.checkedListBox2.SetItemChecked(i, check);
}
}
private IEnumerable<string> ReadInstallerLines()
{
var lin = (path + "config.ini").ToString();
var lines = File.ReadAllLines(lin);
string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile="))
.Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault();
string pathTemp = @"C:\temp\";
string[] pathArr = InstallerFile.Split('\\');
string[] fileArr = pathArr.Last().Split('\\');
string fileArr1 = String.Join(" ", fileArr);
string installerfilename = pathTemp + fileArr1;
string installertext = File.ReadAllText(installerfilename);
return File.ReadLines(pathTemp + fileArr1);
}
private void SetAllProductsChecked(IList<string> installerLines, bool check)
{
for (var i = 0; i < installerLines.Count; i++)
{
if (installerLines[i].Contains("product="))
{
installerLines[i] = check
? installerLines[i].Replace("#product", "product")
: installerLines[i].Replace("product", "#product");
}
if (installerLines[i].Contains("product."))
{
installerLines[i] = check
?installerLines[i].Replace("#product.", "product.")
: installerLines[i].Replace("product.", "#product.");
}
}
}
private void SaveInstaller(IEnumerable<string> installerLines)
{
var lin = (path + "config.ini").ToString();
var lines = File.ReadAllLines(lin);
string InstallerFile = lines.Where(txt => txt.Contains("IstallerFile="))
.Select(txt => txt.Split('=')[1].Replace("\"", "")).FirstOrDefault();
string pathTemp = @"C:\temp\";
string[] pathArr = InstallerFile.Split('\\');
string[] fileArr = pathArr.Last().Split('\\');
string fileArr1 = String.Join(" ", fileArr);
string installerfilename = pathTemp + fileArr1;
File.WriteAllLines(installerfilename, installerLines);
}
}
First works, I can check the boxes from the list, but when I try to make click on checkBox1 I have the next error: The process cannot access the file 'C:\temp\installer_input.txt' because it is used by another process.
How I can make program to works? And how I can optimize my code ?
回答1:
Basically a single thread/process can access a resource which is the file in this case at one instance what you can do is use EventWaitHandle to wait untill some other process or thread has occupied the file like this:
EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES");
waitHandle.WaitOne();
/* process file*/
waitHandle.Set();
来源:https://stackoverflow.com/questions/32984830/how-i-can-close-a-text-file-after-i-edited