DOBON.NET DOBON.NETプログラミング掲示板過去ログ

マルチスレッドでのプチフリーズ

環境/言語:[OS : Windows 7 / 言語 : C# / .NET Framework : 4]
分類:[.NET]

【解決したい問題】

VisualStudio2010ExpressのC#で、ハンディスキャナを用いたシステムを作成しています。

以下の流れのシステムになりますが、作業を何度も繰り返していると
100〜200回に1回の頻度で、1.のタイミングで10〜20秒ほどフリーズしてしまいます。

1.ハンディでバーコードをスキャン(COM7)
2.スキャンしたデータを保持し、データを別システムへ流す(COM8)
3.別システムでファイルを生成(1〜2秒後)
4.FileSystemWatcherでファイル生成を検知し、DB登録

以下ソースの概略です。
ログはDebug出力とlog4netを併用して確認しています。

private static readonly log4net.ILog logger =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private List<string> Stack = new List<string>();
private SerialPort receivePort;
private SerialPort sendPort;
private FileSystemWatcher watcher = new FileSystemWatcher();

// コンストラクタでSerialPortとFileSystemWatcherの初期化をしています。

// スキャンデータ
private void ReceiveData(object sender, SerialDataReceivedEventArgs e) {
byte[] receive = new byte[receivePort.BytesToRead];
receivePort.Read(receive, 0, receive.GetLength(0));
string data = Encode.GetString(receive);

Debug.WriteLine("[Receive1] " + data);
logger.Debug("[Receive1] " + data);

// ※ここでフリーズする。

Debug.WriteLine("[Receive2] " + data);
logger.Debug("[Receive2] " + data);

// dataを判定する処理など
Thread.Sleep(1000);

// スキャンしたデータを保持
lock (((ICollection)this.Stack).SyncRoot) {
if (!this.Stack.Any(a => a == data) {
this.Stack.Add(data);
}

// 別システム(COM8)へデータを流す
byte[] send = Encode.GetBytes(data);
sendPort.Write(send, 0, send.GetLength(0));
Debug.WriteLine("[Send] " + data);
logger.Debug("[Send] " + data);
}

// ファイル監視
void watcher_Created(object sender, FileSystemEventArgs e) {
if (e.ChangeType == WatcherChangeTypes.Created) {
Debug.WriteLine("[Create] " + e.FullPath);
logger.Debug("[Create] " + e.FullPath);
string fileName = Path.GetFileName(e.FullPath);

lock (((ICollection)this.Stack).SyncRoot) {
string data = this.Stack.Find(a => a == fileName);

// DB登録処理など
Thread.Sleep(1000);

// スタックから削除
this.Stack.Remove(fileName);
Debug.WriteLine("[Remove] " + fileName);
logger.Debug("[Remove] " + fileName);
}
}
}

フリーズした際、VisualStudioの出力ログには以下のように出力されます。

2015/03/07 16:10:04.114 : [Create] C:\.....\XXXXXX-9999999999-0001.txt
2015/03/07 16:10:04.332 : [Receive1] XXXXXX-9999999999-0002
スレッド '<名前がありません>' (0x1394) はコード 0 (0x0) で終了しました。
2015/03/07 16:10:25.298 : [Receive2] XXXXXX-9999999999-0002
2015/03/07 16:10:25.720 : [Remove] XXXXXX-9999999999-0001

[Receive1]のログを出力した直後にスレッド終了が来る形で毎回フリーズするため、
スレッド終了時に何かしら原因があるのか…
バーコードスキャンとファイル監視でスレッドが入り乱れてしまう為
デッドロック的な問題があるのか…
問題の切り分けもままならない状態です。

フリーズの原因、または調査方法などご教示頂ければと思います。
よろしくお願いいたします。
2015/03/08(Sun) 18:13:59 編集(投稿者)

「※ここでフリーズする」というこのコードで再現するのだとしたら、log4net の log.Debug メソッド実行の問題のように見えます。
log4net の Debug メソッド呼び出しを削っても、同じ箇所でフリーズするのでしょうか?
Azulean様回答ありがとうございます。

log4netの部分をコメントアウトして実施したところ、1000回繰り返してもフリーズしませんでした。

直接的な原因はわかりませんでしたが、
まずはlog4netを使用しないか、もしくはフリーズしても影響しない場所でロギングするようにして進めようかと思います。

非常に助かりました。ありがとうございました!
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板