protected override void ReadFile(string file, Stream stream, OperationInterop interop) { if (UseEncoding1251 && UseEncoding866) throw new InvalidOperationException("Установлены взаимоисключающие параметры кодировки"); DbfReader dbfReader = new DbfReader(); try { dbfReader.Open(stream, UseEncoding1251 ? Windows1251 : UseEncoding866 ? CP866 : null); Columns = dbfReader.Columns; Data = new List<Dictionary<string, object>>(); Dictionary<string, object> record = null; while ((record = dbfReader.ReadRecord()) != null) { Data.Add(record); } } finally { try { dbfReader.Close(); } catch { } } }
/// <summary> /// Сформатировать данные в поток /// </summary> /// <param name="data">Коллекция массивов значений</param> /// <exception cref="InvalidOperationException">Не установлен выходной поток</exception> internal void Format(IEnumerable<object[]> data, OperationInterop interop) { if (Streams.Count == 0) { throw new InvalidOperationException("Не установлен выходной поток"); } OnBeforeFormatting(); CustomFormat(data, interop); OnAfterFormatting(); }
internal void ReadFiles(OperationInterop interop) { if (Streams.Count == 0) { throw new InvalidOperationException("Не установлен входной файл"); } OnBeforeFileReading(); foreach (var stream in Streams) { // >>> interop.SetStatusText("Чтение файла " + stream.Key); interop.ThrowIfCancellationRequested(); // <<< ReadFile(stream.Key, stream.Value, interop); } OnAfterFileReading(); }
protected abstract void ReadFile(string file, Stream stream, OperationInterop interop);
protected abstract void ExecuteExchange(OperationInterop interop);
public void Execute(OperationInterop interop) { ExecuteExchange(interop); }
/// <summary> /// Запуск последовательно /// </summary> /// <param name="operation"></param> /// <returns></returns> private OperationObject RunSerial(ICompositeOperation operation) { var operations = operation.GetOperations(); if (operations == null || operations.Length == 0) { throw new ArgumentException("No any operation to run ", "consequentOperations"); } // Инициализация int n = operations.Length; var tokenSource = new CancellationTokenSource(); var commonState = new InteropState(); var mockOperationObj = new OperationObject { OperationId = GetNewIndex() }; var mockInterop = new OperationInterop(mockOperationObj, tokenSource.Token, commonState); OperationObject[] conseqOperationObjects = new OperationObject[n]; // Создание объектов представления операций for (int i = 0; i < n; ++i) { conseqOperationObjects[i] = new OperationObject { Parent = mockOperationObj }; mockOperationObj.Children.Add(conseqOperationObjects[i]); } Task chainEnd = null; Task firstTask = null; bool finalSet = false; // Создание цепочки выполнения for (int i = 0; i < n; ++i) { // --> Переменные для замыкания var j = i; var thisOperation = operations[i]; var thisOperationObj = conseqOperationObjects[i]; var thisInterop = new OperationInterop(thisOperationObj, tokenSource.Token, commonState); // <-- thisOperationObj.OperationId = GetNewIndex(); thisOperationObj.Name = thisOperation.OperationInfo.Name; // Chain :: Выполнение операции if (chainEnd == null) { // Первая операция chainEnd = new Task(() => { mockOperationObj.Status = OperationStatus.Running; operation.OnChainStart(mockInterop); thisOperation.Execute(thisInterop); }, tokenSource.Token); firstTask = chainEnd; } else { // Цепляем следующие chainEnd = chainEnd.ContinueWith((_, __) => { tokenSource.Token.ThrowIfCancellationRequested(); thisOperation.Execute(thisInterop); }, null, tokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current); } // Chain :: Обработка законченной операции chainEnd = chainEnd.ContinueWith(et => { thisOperation.Dispose(); // Установка статуса собственной операции thisOperationObj.Status = et.Status.ToOperationStatus(); // Установка статуса главной репрезентативной операции if (!finalSet) { if (et.Status != TaskStatus.RanToCompletion) { // Любая операция завершилась неуспешно mockOperationObj.Status = et.Status.ToOperationStatus(); thisOperationObj.Exception = et.Exception; mockOperationObj.Exception = et.Exception; if (!IsBeingWatched(mockOperationObj)) { Notifier.Notify("Операция #" + mockOperationObj.OperationId, "Операция не завершена", null); } tokenSource.Cancel(); finalSet = true; } else if (j == n - 1) { // Последняя операция завершилась успешно mockOperationObj.Status = OperationStatus.RanToCompletion; mockOperationObj.Progress = 100; if (!IsBeingWatched(mockOperationObj)) { Notifier.Notify("Операция #" + mockOperationObj.OperationId, "Операция завершена", null); } tokenSource.Cancel(); finalSet = true; } } if (j < n - 1) { // Установка прогресса главной репрезентативной операции UpdateMockOperationProgress(mockOperationObj, n, j + 1); } }); thisOperationObj.Status = OperationStatus.Created; } chainEnd.ContinueWith(t => { operation.OnChainEnded(); operation.Dispose(); }); // Обработка и запуск выполнения цепочки mockOperationObj.Status = OperationStatus.Created; mockOperationObj.Added = DateTime.Now; mockOperationObj.Name = operation.OperationInfo.Name; AddOperation(mockOperationObj); AddUnit(mockOperationObj.OperationId, new OperationUnit { CancellationTokenSource = tokenSource, ChainEndTask = chainEnd }, operations); firstTask.Start(); return mockOperationObj; }
/// <summary> /// Запуск параллельно /// </summary> /// <param name="operation"></param> /// <returns></returns> private OperationObject RunParallel(ICompositeOperation operation) { var operations = operation.GetOperations(); if (operations == null || operations.Length == 0) { throw new ArgumentException("No any operation to run ", "consequentOperations"); } // Инициализация int n = operations.Length; var tokenSource = new CancellationTokenSource(); var commonState = new InteropState(); var mockOperationObj = new OperationObject { OperationId = GetNewIndex() }; var mockInterop = new OperationInterop(mockOperationObj, tokenSource.Token, commonState); OperationObject[] parallelOperationObjects = new OperationObject[n]; // Создание объектов представления операций for (int i = 0; i < n; ++i) { parallelOperationObjects[i] = new OperationObject { Parent = mockOperationObj }; mockOperationObj.Children.Add(parallelOperationObjects[i]); } List<Task> tasks = new List<Task>(); int finishedCount = 0; bool totalSuccess = true; bool canceled = false; // Создание цепочки выполнения for (int i = 0; i < n; ++i) { // текущая задача Task task = null; // --> Переменные для замыкания var j = i; var thisOperation = operations[i]; var thisOperationObj = parallelOperationObjects[i]; var thisInterop = new OperationInterop(thisOperationObj, tokenSource.Token, commonState); // <-- thisOperationObj.OperationId = GetNewIndex(); thisOperationObj.Name = thisOperation.OperationInfo.Name; // Запуск операции task = new Task(() => { thisOperationObj.Status = OperationStatus.Running; thisOperation.Execute(thisInterop); }, tokenSource.Token); // Обработка законченной операции task.ContinueWith(et => { thisOperation.Dispose(); finishedCount++; // Установка статуса собственной операции thisOperationObj.Status = et.Status.ToOperationStatus(); if (et.Status != TaskStatus.RanToCompletion) { thisOperationObj.Exception = et.Exception; totalSuccess = false; if (et.Status == TaskStatus.Canceled) { canceled = true; tokenSource.Cancel(); } } // Установка прогресса главной репрезентативной операции UpdateMockOperationProgress(mockOperationObj, n, finishedCount); // завершились все задачи // Установка статуса главной репрезентативной операции if (finishedCount == n) { if (totalSuccess) { // Последняя операция завершилась успешно mockOperationObj.Status = OperationStatus.RanToCompletion; mockOperationObj.Progress = 100; if (!IsBeingWatched(mockOperationObj)) { Notifier.Notify("Операция #" + mockOperationObj.OperationId, "Операция завершена", null); } } else { mockOperationObj.Status = canceled ? OperationStatus.Canceled : OperationStatus.Faulted; if (!IsBeingWatched(mockOperationObj)) { Notifier.Notify("Операция #" + mockOperationObj.OperationId, "Операция не завершена", null); } } tokenSource.Cancel(); operation.OnChainEnded(); operation.Dispose(); } }); thisOperationObj.Status = OperationStatus.Created; tasks.Add(task); } // Обработка и запуск выполнения цепочки mockOperationObj.Status = OperationStatus.Created; mockOperationObj.Added = DateTime.Now; mockOperationObj.Name = operation.OperationInfo.Name; AddOperation(mockOperationObj); AddUnit(mockOperationObj.OperationId, new OperationUnit { CancellationTokenSource = tokenSource }, operations); operation.OnChainStart(mockInterop); mockOperationObj.Status = OperationStatus.Running; foreach (Task task in tasks) { task.Start(); } return mockOperationObj; }
/// <summary> /// Запустить одну операцию /// </summary> /// <param name="operation">Операция</param> /// <exception cref="System.ArgumentNullException" /> public OperationObject Run(IOperation operation) { if (operation == null) { throw new ArgumentNullException("operation"); } // Инициализация var tokenSource = new CancellationTokenSource(); var operationObj = new OperationObject { OperationId = GetNewIndex() }; var interop = new OperationInterop(operationObj, tokenSource.Token); // Chain :: Выполнение операции var task = new Task(() => { operationObj.Status = OperationStatus.Running; operation.Execute(interop); }, tokenSource.Token); // Chain :: Обработка законченной операции var chainEnd = task.ContinueWith(et => { operationObj.Exception = et.Exception; operationObj.Status = et.Status.ToOperationStatus(); operationObj.Progress = 100; operation.Dispose(); if (!IsBeingWatched(operationObj)) { Notifier.Notify("Операция #" + operationObj.OperationId, "Операция завершена", null); } }); // Обработка и запуск цепочки выполнения AddOperation(operationObj); AddUnit(operationObj.OperationId, new OperationUnit { CancellationTokenSource = tokenSource, ChainEndTask = chainEnd }, operation); operationObj.Status = OperationStatus.Created; operationObj.Name = operation.OperationInfo.Name; task.Start(); return operationObj; }
protected override void ExecuteExchange(OperationInterop interop) { // >>> interop.SetStatusText("Инициализация"); interop.ThrowIfCancellationRequested(); // <<< RaiseBeforeExecuteEvent(); // >>> interop.SetStatusText("Обработка параметров"); // <<< // >>> interop.SetStatusText("Чтение файлов"); interop.ThrowIfCancellationRequested(); interop.SetProgress(10); // <<< // Чтение файлов foreach (var formatter in Formatters) { formatter.ReadFiles(interop); } // >>> interop.SetStatusText("Обработка данных"); interop.ThrowIfCancellationRequested(); interop.SetProgress(50); // <<< // Before foreach (var formatter in Formatters) { formatter.OnBeforeFormatting(); } // Processing foreach (var formatter in Formatters) { interop.ThrowIfCancellationRequested(); var objectSpace = GetObjectSpace(); bool success = false; try { formatter.ProcessData(objectSpace, interop); success = true; } finally { CloseObjectSpace(objectSpace, success); } } // After foreach (var formatter in Formatters) { formatter.OnAfterFormatting(); } // >>> interop.SetStatusText("Постобработка"); interop.SetProgress(99); // <<< RaiseAfterExecuteEvent(); interop.SetProgress(100); }
protected override void CustomFormat(IEnumerable<object[]> objects, OperationInterop interop) { using (var sr = new StreamWriter(Streams.Values.Single(), Encoding ?? Encoding.Default)) { var ch = new CustomHeaderEventArgs(interop); RaiseCustomHeaderEvent(ch); if (!String.IsNullOrEmpty(ch.HeaderText)) { if (listDivider == null) { sr.WriteLine(ch.HeaderText); } else { sr.Write(ch.HeaderText + listDivider); } } foreach (var obj in objects) { if (listDivider == null) { sr.WriteLine(String.Join(elemDivider, obj)); } else { sr.Write(String.Join(elemDivider, obj) + listDivider); } interop.ThrowIfCancellationRequested(); } var cf = new CustomFooterEventArgs(interop, objects); RaiseCustomFooterEvent(cf); if (!String.IsNullOrEmpty(cf.FooterText)) { if (listDivider == null) { sr.WriteLine(cf.FooterText); } else { sr.Write(cf.FooterText + listDivider); } } sr.Flush(); } }
protected abstract void CustomFormat(IEnumerable<object[]> data, OperationInterop interop);
public abstract void ProcessData(IObjectSpace objectSpace, OperationInterop interop);
/// <summary> /// Выполнить операцию /// </summary> /// <param name="interop">Объект взаимодействия</param> public void Execute(OperationInterop interop) { action.Invoke(interop); }
public InteropEventArgs(OperationInterop interop) { Interop = interop; }
public CustomHeaderEventArgs(OperationInterop interop) : base(interop) { }
public CustomFooterEventArgs(OperationInterop interop, IEnumerable<object> data) : base(interop) { Data = data; }
protected override void ReadFile(string file, Stream stream, OperationInterop interop) { if (Reader != null) throw new InvalidOperationException("Текстовый форматировщик поддерживает только один файл."); Reader = new StreamReader(stream, Encoding ?? Encoding.Default); }
protected override void ReadFile(string file, Stream stream, OperationInterop interop) { Workbook.LoadDocument(file, DocumentFormat); }