반응형
안녕하세요 hayee 입니다.
멀티 스레드 환경에서 로그 쓰기를 위해 파일에 접근하는데, 특정 로그가 누락되는 이슈가 있었습니다.
파일 쓰기 전 ReaderWriterLockSlim 을 사용하여 멀티스레드 환경에서 파일 쓰기를 할 때 한 개의 스레드만 접근 가능하도록 하여 이를 해결하였습니다.
◈ 예제 소스
public partial class Form1 : Form
{
Thread m_th1, m_th2;
public Form1()
{
InitializeComponent();
}
private void btnWrite_Click(object sender, EventArgs e)
{
m_th1 = new Thread(() => StartThread1());
m_th1.Name = "test thread 1";
m_th1.IsBackground = true;
m_th1.Start();
Thread.Sleep(100);
m_th2 = new Thread(() => StartThread2());
m_th2.Name = "test thread 2";
m_th2.IsBackground = true;
m_th2.Start();
}
private void StartThread1()
{
int nCount = 0;
while (true)
{
string slog = string.Format("스레드01 - 테스트 로그 / Count:{0}", nCount++);
Log.Writelog(slog);
if (nCount > 200)
nCount = 0;
Thread.Sleep(200);
}
}
private void StartThread2()
{
int nCount = 0;
while (true)
{
string slog = string.Format("스레드02 - 테스트 로그 / Count:{0}", nCount++);
Log.Writelog(slog);
if (nCount > 200)
nCount = 0;
Thread.Sleep(250);
}
}
private void button1_Click(object sender, EventArgs e)
{
if (m_th1 != null)
{
m_th1.Abort();
m_th1 = null;
}
if (m_th2 != null)
{
m_th2.Abort();
m_th2 = null;
}
}
}
class Log
{
static readonly string m_sFolderName = "\\LOG\\";
//static readonly ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();
public static void Writelog(string logMsg)
{
try
{
string sLogFilePath = Directory.GetCurrentDirectory() + m_sFolderName + DateTime.Now.ToString("yyyyMM");
if (!Directory.Exists(sLogFilePath))
{
Directory.CreateDirectory(sLogFilePath);
}
string sFile = sLogFilePath + "\\TestFile_" + DateTime.Now.ToString("yyyyMMdd") + ".log";
if (!File.Exists(sFile))
{
using (StreamWriter sw = File.CreateText(sFile))
{
;
}
}
//m_rwLock.EnterWriteLock();
using (StreamWriter sw = File.AppendText(sFile))
{
string sLog = logMsg.Replace("\n", "");
sw.Write(System.DateTime.Now.ToString("HH:mm:ss.fff: "));
sw.WriteLine(sLog);
sw.Close();
}
}
catch (Exception ex)
{
Trace.WriteLine("Exception Error : " + ex.Message);
}
//finally
//{
// m_rwLock.ExitWriteLock();
//}
}
}
1. 버튼을 누르면 2개의 스레드가 생성된다.
2. 두 개의 스레드는 주기적으로 파일에 Write 동작을 한다.
3. ReaderWriterLockSlim 을 사용하지 않았을 경우 주기적으로 출력창에 Exception error 가 발생함을 확인할 수 있었다.
(Error >> TestFile_20230210.log' 파일은 다른 프로세스에서 사용 중이므로 프로세스에서 액세스할 수 없습니다.)
◈ 실행 결과
4. ReaderWriterLockSlim 관련 주석을 풀고 다시 테스트할 경우 관련 에러가 발생하지 않는 것을 확인할 수 있다.
# 틀린 부분이 있다면 댓글 부탁드립니다. #
# 댓글 달아주시면 늦게라도 블로그 방문하도록 할게요! 감사합니다. #
728x90
반응형
'hayee Study > 코딩_c#' 카테고리의 다른 글
[C#] string 정리 (substring, contain, equal, concat) (52) | 2023.10.29 |
---|---|
[C#] Combobox 사용법. (3) | 2023.10.29 |
[C#] notifyicon 사용법. (프로그램 아이콘 등록하기) (5) | 2023.10.15 |
[C#] 현재 실행되고 있는 프로그램 경로 설정하기 (60) | 2023.10.14 |
[C#] DateTime 에 대하여 (0) | 2023.10.12 |