Inicializando campos FileStream e StreamWriter em uma class de serviço

Eu fiz este código fora dos methods, porque eu preciso fechar e dispor o streamwriter e filestream no método OnStop ():

private Timer timer = new Timer(); private FileStream fs = new FileStream(@"D:\Hello.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite); private StreamWriter sw = new StreamWriter(fs); //The fs is in red line, having error 

No entanto, o fs dentro do novo StreamWriter solicita o erro “Um inicializador de campo não pode fazer referência ao campo, método ou propriedade não estático …”. Então eu fiz o FileStream estático:

 private static FileStream fs = new FileStream(@"D:\Hello.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite); 

Quando eu corri o programa, ele não escreve no arquivo de texto e concluiu que é por causa da estática. Eu pesquisei sobre isso e li isso : “Uma class pode ser declarada estática, indicando que ela contém apenas membros estáticos. Não é possível criar instâncias de uma class estática usando a nova palavra-chave. Classes estáticas são carregadas automaticamente pelo .NET Framework Common Language Runtime (CLR) quando o programa ou namespace contendo a class é carregado. ”

Este é o meu código de amostra:

 public partial class Service1 : ServiceBase { private Timer timer = new Timer(); private FileStream fs = new FileStream(@"D:\Hello.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite); private StreamWriter sw = new StreamWriter(fs); //The fs is in red line, having error. Look in my description for error's details public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { timer.Elapsed += new ElapsedEventHandler(WriteText); timer.Interval = 5000; //5 seconds timer.Start(); } public void WriteText(object source, ElapsedEventArgs e) { sw.WriteLine(DateTime.Now + " Windows Service"); } protected override void OnStop() { sw.Close(); sw.Dispose(); fs.Close(); fs.Dispose(); timer.Stop(); } } 

O que você acha que eu deveria fazer?

O que você fez deve funcionar bem, mas não é uma boa maneira de fazer isso, então não vale a pena investigar por que não está funcionando. Ter variables ​​estáticas em uma class não torna a class estática.

Apenas declare as variables ​​sem inicializadores, depois defina as variables ​​quando quiser abrir o arquivo:

 public partial class Service1 : ServiceBase { private Timer timer; private FileStream fs; private StreamWriter sw public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { fs = new FileStream(@"D:\Hello.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite); sw = new StreamWriter(fs); timer = new Timer(); timer.Elapsed += new ElapsedEventHandler(WriteText); timer.Interval = 5000; //5 seconds timer.Start(); } public void WriteText(object source, ElapsedEventArgs e) { sw.WriteLine(DateTime.Now + " Windows Service"); } protected override void OnStop() { timer.Stop(); // Stop the timer before closing the file sw.Close(); sw.Dispose(); fs.Close(); fs.Dispose(); } } 

Não os torne estáticos. Basta mover o código de boot dos inicializadores de campo para o construtor. E não se esqueça de adicionar um método Dispose que os disponha.

Você não precisa de um campo estático, apenas mova a boot para o seu construtor:

 private FileStream fs; private StreamWriter sw; public MyClass() { fs = new FileStream(@"D:\Hello.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite); sw = new StreamWriter(fs); } 

Para ter certeza, seu método OnStop() é realmente chamado e o stream é descartado, implemente IDisposable em sua class e chame OnStop() no final do seu método Dispose() .