public static class FileTransform
{
public static void Transform(string inFilePath, string outFilePath, IStringsTransform traitment,
Action<string> showError, Func<string, bool> showErrorWithRetry, Action<bool> traitmentDone)
if (!File.Exists(inFilePath))
FileNotFoundShowError(inFilePath, showError);
else if (!Directory.Exists(Path.GetDirectoryName(outFilePath)))
DirectoryNotFoundShowError(outFilePath, showError);
else
var bg = new BackgroundWorker();
bg.DoWork += (s, e) =>
e.Result = false;
while (true)
try
FileUtil.WriteLines(outFilePath, traitment.Do(FileUtil.GetLines(inFilePath)));
e.Result = true;
}
catch (FileNotFoundException)
catch (DirectoryNotFoundException)
catch (IOException)
if (showErrorWithRetry(string.Format(ErrorResources.IOException, outFilePath)))
continue;
catch (Exception ex)
showError(string.Format(ErrorResources.FileNotFoundException,
string.Concat(ex.GetType(), " : ", ex.Message)));
break;
};
bg.RunWorkerCompleted += (s, e) =>
if (traitmentDone != null)
traitmentDone((bool)e.Result);
bg.RunWorkerAsync();
private static void DirectoryNotFoundShowError(string directoryPath, Action<string> showError)
showError(string.Format(ErrorResources.DirectoryNotFoundException, Path.GetDirectoryName(directoryPath)));
private static void FileNotFoundShowError(string filePath, Action<string> showError)
showError(string.Format(ErrorResources.FileNotFoundException, filePath));
private static Dictionary<string, BackgroundWorker> _traitmentsRunning = new Dictionary<string, BackgroundWorker>();
private static object _lockObject = new object();
private static object _bwLockObject = new object();
if (!Directory.Exists(Path.GetDirectoryName(outFilePath)))
lock (_lockObject)
if (!(File.Exists(inFilePath) || _traitmentsRunning.ContainsKey(inFilePath)))
var bw = new BackgroundWorker();
bw.DoWork += (s, e) =>
_traitmentsRunning.Remove(outFilePath);
bw.RunWorkerCompleted += (s, e) =>
StartBWAndCache(inFilePath, outFilePath, bw);
private static void StartBWAndCache(string inFilePath, string outFilePath, BackgroundWorker bw)
lock (_bwLockObject)
string filePath = null;
if (_traitmentsRunning.ContainsKey(inFilePath))
filePath = inFilePath;
else if (_traitmentsRunning.ContainsKey(outFilePath))
filePath = outFilePath;
if (filePath != null)
_traitmentsRunning[filePath].RunWorkerCompleted +=
(s, e) => StartBWAndCache(inFilePath, outFilePath, bw);
_traitmentsRunning.Add(outFilePath, bw);
bw.RunWorkerAsync();