バックグラウンド:
「セマフォ」ファイルを処理するサービスに取り組んでいます。これらは、データベースに読み込む必要がある xml ファイルへのリンクを含む 1 つのディレクトリに配置された txt ファイルです。以前のバージョンはありましたが、データ損失について不注意だったので、私の新しいサービスは、どのような場合でもファイルを処理するために非常に慎重です.
仕様:
私は a) 新しいファイルを 'Processing' フォルダーにコピーするために使用される BackgroundWorker プールを持っています (Unix マシン上にあるため、コピーによって使用できるようにファイルのアクセス許可が変更されます)、それをキューに追加し、b ) ファイルの内容を処理します。
ファイルを開いたままにしたくないので、SemaphoreFile クラスにはその場所への参照が含まれ、ファイルの読み取りと書き込みが管理されます。デストラクタでファイルのクリーンアップも処理するため、悲惨なクラッシュでもデータが保持されます。
期待される:
ファイルを処理するときの RunWorkerCompleted メソッドでは、dispose メソッドを呼び出せるように、semaphoreFile が返されることを期待しています。すべてが成功した場合、ファイルは削除され、semaphoreFile インスタンスはスコープを離れます。プロセスでエラーが発生した場合は、多くの場合そうすべきですが、エラーを処理し、ファイルを問題ありとしてマークし (そのデータの下のファイルにエラーを書き込み、それを新しい「Prolematic」フォルダーに移動します)、再び破棄します。 ().
throw new NotImplementedException("No error or results"); を追加しました。これがヒットしないようにする必要があるため、デバッガーで検索できます。セマフォ ファイルを整理するには、セマフォ ファイルへの参照が必要です。これができなければ、失われてしまいます。
問題:
現在の問題は、バックグラウンド ワーカーが「GetResult」を実行するとエラーが発生するが、e.Error が null になることです。これは、e.Result も null であることを意味し、見たくなかったこのエラーに行き詰まります。
SemaphoreFile.GetResults に例外がある場合、e.Error が null になるのはなぜですか?
コード スニペット
実行する:
public static void Execute()
{
while (_isActive)
{
SemaphoreFile semaphoreFile;
lock (ThreadLock)
{
int threadIndex;
bool hasFreeThread = TryGetFreeThread(out threadIndex);
bool hasSemaphore = SemaphoreQueue.HasNext;
if (hasFreeThread && hasSemaphore)
{
semaphoreFile = SemaphoreQueue.Next;
_threads[threadIndex].DoWork += delegate(object sender, DoWorkEventArgs args)
{
try
{
BackgroundWorker bw = (BackgroundWorker)sender;
if (bw.CancellationPending)
args.Cancel = true;
args.Result = semaphoreFile.GetResults(bw);
if (bw.CancellationPending)
args.Cancel = true;
}
catch (Exception e)
{
Writelog.Write("An error occured processing file " + semaphoreFile + ":" + e.Message);
Writelog.WriteException(e);
}
}
;
_threads[threadIndex].RunWorkerCompleted += ThreadRunWorkerCompleted;
Debug.Print("Starting Thread @ index " + threadIndex);
_threads[threadIndex].RunWorkerAsync();
}
}
}
}
RunWorkerCompleted:
private static void ThreadRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
if (e.Error.GetType() == typeof(SemaphoreFileException))
{
SemaphoreFileException semaphoreFileException = (SemaphoreFileException)e.Error;
semaphoreFileException.SemaphoreFile.MarkAsProblematic(e.Error);
semaphoreFileException.SemaphoreFile.Dispose();
}
else
{
if (!(e.Error.GetType() == typeof(SemaphoreResultFileException)))
{
throw e.Error;
}
SemaphoreResultFileException semaphoreResultFileException = (SemaphoreResultFileException)e.Error;
semaphoreResultFileException.SemaphoreFile.MarkAsProblematic(e.Error);
semaphoreResultFileException.SemaphoreFile.Dispose();
}
}
else
{
if (!e.Cancelled)
{
if (e.Result == null)
{
throw new NotImplementedException("No error or results");
}
if (e.Result.GetType() == typeof(SemaphoreFile))
{
SemaphoreFile semaphoreFile = (SemaphoreFile)e.Result;
semaphoreFile.Dispose();
}
}
}
}
SemaphoreFile.GetResults
public SemaphoreFile GetResults(BackgroundWorker backgroundWorker)
{
if (!File.Exists(_fileInfo.FullName))
throw new SemaphoreFileException(this, string.Format("Semaphore {0} is missing", _fileInfo.FullName));
if (!Parse())
throw new SemaphoreFileException(this, string.Format("Semaphore {0} failed to parse correctly.", _fileInfo.FullName));
if (!_resultFiles.Any())
throw new SemaphoreFileException(this, string.Format("Semaphore {0} contains no Results.", _fileInfo.FullName));
List<Exception> resultFileExceptions = new List<Exception>();
foreach (ResultFile resultFile in _resultFiles)
{
if (backgroundWorker.CancellationPending)
{
IsFinished = false;
return this;
}
try
{
resultFile.Process();
string line = resultFile.ToString();
if (_lines.Contains(resultFile.ToString()))
{
_lines.Remove(line);
if (!_lines.Contains("Lines done in last run:"))
{
_lines.Add("Run @ " + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString());
_lines.Add("Lines done in last run:");
}
_lines.Add(resultFile.ToString());
}
}
catch (Exception exception)
{
resultFileExceptions.Add(exception);
}
}
if (resultFileExceptions.Count > 0)
{
_fileInfo = MoveFile(SemaphoreSubFoldersEnum.Problematic);
throw new SemaphoreResultFileException(this, resultFileExceptions, string.Format("Results in Semaphore {0} contained errors:", _fileInfo.FullName));
}
return this;
}
長い間ありがとうございました^_^