简体   繁体   中英

better way of invoking thread and logging to text file in C#

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.

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.

您可以使用线程安全的log4net ,而不用编写自己的日志功能。

The classic version would be:

  • Have a dedicated logger thread, most of the time waiting on an AutoResetEvent
  • Have a (threadsafe) Queue
  • Logging is initiated by writing to that Queue and setting the AutoResetEvent
  • The logger thread wakes up, empties the queue into the file, then sleeps again

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM