Попытка открыть объекты Sytem.IO
Я делаю программу, которая позволяет вам бросать пять разных типов многогранных "кубиков", и когда вы бросаете число, я хочу, чтобы оно сохранялось в текстовом файле. В верхней части моей формы есть элемент полосы меню, который вы нажимаете, он закрывает StreamWriter и FileStream и открывает вторую форму, показывающую, какие числа были прокручены и на какой кубик они были прокручены (я имею в виду, что это просто свернутые числа теперь для простоты) и это отображает нормально. Но когда я закрываю Reader, Stream и вторую форму и возвращаюсь к первой форме, я пытаюсь снова открыть Writer и Stream, и она сообщает мне, что она уже используется.
Код моей первой формы:
using System;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Random ran = new Random();
static FileStream outFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter writer = new StreamWriter(outFile);
private int ranNum;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ranNum = ran.Next(1, 21);
Display();
}
private void button2_Click(object sender, EventArgs e)
{
ranNum = ran.Next(1, 13);
Display();
}
private void button3_Click(object sender, EventArgs e)
{
ranNum = ran.Next(1, 5);
Display();
}
private void button4_Click(object sender, EventArgs e)
{
ranNum = ran.Next(1, 9);
Display();
}
private void button5_Click(object sender, EventArgs e)
{
ranNum = ran.Next(1, 11);
Display();
}
private void Display()
{
lblNum.Text = String.Format("{0}", ranNum);
lblNum.Visible = true;
writer.WriteLine(ranNum);
}
private void historyToolStripMenuItem_Click(object sender, EventArgs e)
{
tabControl1.SelectedIndex = 1;
writer.Close();
outFile.Close();
History history = new History();
history.ShowDialog();
}
private void button1_Click_1(object sender, EventArgs e)
{
FileStream outFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter writer = new StreamWriter(outFile);
tabControl1.SelectedIndex = 0;
}
}
}
Код моей второй формы:
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class History : Form
{
public History()
{
InitializeComponent();
}
static private FileStream inFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.Open, FileAccess.Read);
private StreamReader reader = new StreamReader(inFile);
private void History_Load(object sender, EventArgs e)
{
string item;
item = reader.ReadLine();
try
{
lstHistory.Items.Add(item);
}
catch (Exception)
{
lstHistory.Font = new Font(lstHistory.Font.Name, 12, lstHistory.Font.Unit);
lstHistory.Items.Add("You have not rolled any numbers");
}
}
}
}
1 ответ
Вам нужно правильно высвободить неуправляемые ресурсы (в вашем случае файл), как только это будет сделано. Позвоните Dispose()
функция на stream
как только закончите с этим:
if(inFile != null){
inFile.Dispose();
}
И даже лучше, заверните его в using()
как это:
using(FileStream outFile = new FileStream(@"H:\C#\Independant Projects\VirtualDice\History.txt", FileMode.OpenOrCreate, FileAccess.Write)){
StreamWriter writer = new StreamWriter(outFile);
tabControl1.SelectedIndex = 0;
}
using
автоматически позвонит Dispose()
для вас в нужное время надлежащим образом (т.е. он проверяет, является ли объект null
сначала перед звонком Dispose()
на нем, чтобы избежать `нулевого исключения). Проверьте эту ссылку для более подробной информации об использовании оператора.
Однако, если у вас есть один и тот же код во многих местах, возможно, стоит его обернуть singleton
шаблон. Прочтите эту статью Microsoft о том, как написать шаблон синглтона в C#.