簡體   English   中英

在C#中調用線程並記錄到文本文件的更好方法

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

我有一個將日志記錄寫為文本文件的程序。

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();
            }
        }
    }
}

然后我有一個功能。

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();
}

內部的兩個函數( BoardingPass_Print()BaggageTag_Print() )調用相同的日志記錄函數。

logging.log.Info(username, "Query Trace > ", sql);

由於我調用線程方法,我認為我遇到了錯誤:

該進程無法訪問文件'C:\\ Folder \\ 2012-01-17-Name.txt',因為該文件正在被另一個進程使用。

任何人都可以給我更好的解決方案來與線程交互並記錄到文本文件,而不會遇到這樣的錯誤消息嗎?

每個建議將不勝感激。

您將必須使編寫線程安全(帶有lock )。 您當前的代碼也不是異常安全的。 您可以使用正確的庫方法來解決這兩個問題。

您不能(輕松地)確保可以從多個進程安全訪問文件,但是只要文件僅由應用程序的1個實例編寫,就可以同步線程。

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是靜態方法,它將正確處理新文件/現有文件問題和資源管理。

您可以使用線程安全的log4net ,而不用編寫自己的日志功能。

經典版本為:

  • 擁有專用的記錄器線程,大部分時間都在等待AutoResetEvent
  • 有一個(線程安全的)隊列
  • 通過寫入該隊列並設置AutoResetEvent來啟動日志記錄
  • 記錄器線程喚醒,將隊列清空到文件中,然后再次休眠

您可以選擇為此而選擇的預先開發的框架,或者如果您希望避免依賴性,則可以自己編寫幾行。

就像其他人所說的那樣,請使用NLog,log4Net,企業庫等,因為滾動現有的日志記錄邏輯將是不全面的,因為已經提供了這些產品。

但是,如果您希望保持原樣...一個建議可能是將日志信息發送到隊列(例如MSMQ),然后讓另一個單獨的進程輪詢隊列並將信息保存到文本文件中。

如果您不想使用任何日志記錄框架,則必須至少使用lock語句來保證線程安全。

您也可以使用Singleton代替靜態方法,並保持日志文件打開,直到應用結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM