Reputation: 4474
I have a program which write logging as Text File.
namespace logging
{
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
public class log
{
private static string lpath;
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
public static void Info(string user, string info, string txt)
{
StreamWriter writer;
string str = Assembly.GetExecutingAssembly().GetName().CodeBase.ToString();
.....
if (!File.Exists(path))
{
writer = new StreamWriter(path, true);
writer.WriteLine(str3 + " " + info + " => " + txt);
writer.Flush();
writer.Close();
}
else
{
writer = File.AppendText(path);
writer.Write(str3 + " " + info + " => " + txt + "\n");
writer.Flush();
writer.Close();
}
}
}
}
Then I have a function.
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Thread thread_BP_Print = new Thread(BoardingPass_Print);
thread_BP_Print.Start();
// Simultaneously, do something on the main thread.
BaggageTag_Print();
bgw.RunWorkerAsync();
}
Two of the inner functions (BoardingPass_Print()
and BaggageTag_Print()
) call the same logging function.
logging.log.Info(username, "Query Trace > ", sql);
Because of my invoking thread methods, I think I face the error:
The process cannot access the file 'C:\Folder\2012-01-17-Name.txt' because it is being used by another process.
Could anyone give me better solution to interact with thread and logging to text file without facing error message like this?
Every suggestion will be really appreciated.
Upvotes: 0
Views: 6341
Reputation: 620
If you don't want to use any logging framework, you must at least use lock
statement to be thread-safe.
You can also use Singleton instead of static method and keep your log file open until appliaction ends.
Upvotes: 1
Reputation: 273179
You would have to make the writing thread-safe (with lock
). Your current code also is not exception-safe.
You can solve both issues by using the right library method.
You cannot (easily) assure safe access to a file from multiple processes, but as long as its only written by 1 instance of the application you can sync the threads.
private static object locker = new object();
public static void Info(string user, string info, string txt)
{
string str = Assembly.GetExecutingAssembly().GetName().CodeBase.ToString();
string str3 = ...
lock (locker)
{
File.AppendAllText(path, str3 + " " + info + " => " + txt + "\n");
}
}
AppendAllText
is a static method, it will handle the new/existing file issue and the resource management correctly.
Upvotes: 2
Reputation: 16802
Like others have said use NLog, log4Net, Enterprise Library, etc. as rolling your own logging logic will not be a comprehensive as the offerings already available.
However if you want to keep things as they are... one suggestion might be to send the log information to a queue (say MSMQ) and have another separate process poll the queue and save the information to your text files.
Upvotes: 1
Reputation: 65254
The classic version would be:
You can chose from a choice of predeveloped frameworks for that or roll your own in a few lines, if you want to avoid the dependency.
Upvotes: 1