private void WaitForConnectionCallBack(IAsyncResult iar) { try { Stopwatch sw = new Stopwatch(); sw.Start(); Console.WriteLine("=> Receiving pipe message"); NamedPipeServerStream pipeServer = (NamedPipeServerStream)iar.AsyncState; pipeServer.EndWaitForConnection(iar); //PipeMessage.Invoke(stringData); IFormatter fmtr = new BinaryFormatter(); //fmtr.Binder = new MessageAssemblyBinder(); PipeMessage msg_in = (PipeMessage)fmtr.Deserialize(pipeServer); // <- possibly the slow bit. Maybe use named pipes for signalling and shared memory for chunks. pipeServer.Close(); pipeServer = null; pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); sw.Stop(); Console.WriteLine("\t --Pipe message received, time: " + sw.Elapsed.TotalMilliseconds + " ms"); pipeServer.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), pipeServer); } catch (Exception e) { throw new SystemException(e.Message); } }
/// <summary> /// Initialise the Compute Core with source data coming from a named pipe message /// </summary> /// <param name="sourceData">The named pipe message containing workbook data</param> public ComputeCore(PipeMessage sourceData) { if (sourceData.dict_sheet_name_map.Count == 0) { load_error = true; return; } this.dict_loader_array_formulas = sourceData.dict_loader_array_formulas; this.dict_loader_constants = sourceData.dict_loader_constants; this.dict_loader_formulas = sourceData.dict_loader_formulas; this.dict_loader_string_constants = sourceData.dict_loader_string_constants; this.dict_sheet_name_map = sourceData.dict_sheet_name_map; }
public void Send(PipeMessage msg_in) { try { NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.Asynchronous); pipeStream.Connect(timeOut); IFormatter fmtr = new BinaryFormatter(); fmtr.Serialize(pipeStream, msg_in); } catch (Exception except) { throw new SystemException(except.Message); } }
private void GetSheetDataIPC() { Excel.Workbook activeBook; Application.ScreenUpdating = false; try { activeBook = Application.ActiveWorkbook; } catch (Exception) { return; } Dictionary <string, int> dict_sheet_name_map = new Dictionary <string, int>(activeBook.Sheets.Count); List <ConcurrentDictionary <string, float> > dict_constants = new List <ConcurrentDictionary <string, float> >(activeBook.Sheets.Count); List <ConcurrentDictionary <string, string> > dict_string_constants = new List <ConcurrentDictionary <string, string> >(activeBook.Sheets.Count); List <ConcurrentDictionary <string, Tools.ArrayFormulaInfo> > dict_loader_array_formulas = new List <ConcurrentDictionary <string, Tools.ArrayFormulaInfo> >(activeBook.Sheets.Count); List <ConcurrentDictionary <string, string> > dict_formulas = new List <ConcurrentDictionary <string, string> >(activeBook.Sheets.Count); //get sheets for (int i = 1; i <= activeBook.Sheets.Count; i++) { Excel.Worksheet sheet = activeBook.Sheets.get_Item(i); dict_sheet_name_map.Add(sheet.Name, i); dict_constants.Add(new ConcurrentDictionary <string, float>(StringComparer.Ordinal)); dict_formulas.Add(new ConcurrentDictionary <string, string>(StringComparer.Ordinal)); dict_string_constants.Add(new ConcurrentDictionary <string, string>(StringComparer.Ordinal)); dict_loader_array_formulas.Add(new ConcurrentDictionary <string, Tools.ArrayFormulaInfo>(StringComparer.Ordinal)); } Stopwatch sw = new Stopwatch(); sw.Start(); Parallel.For(0, dict_sheet_name_map.Count, sh => { Excel.Range usedRange; try { usedRange = activeBook.Sheets.get_Item(sh + 1).UsedRange; } catch (Exception) { return; } string start_address = usedRange.Cells[1, 1].Address.Replace("$", ""); object[,] arr_formulas = usedRange.Formula as object[, ]; object[,] arr_values = usedRange.Value2 as object[, ]; //object[,] arr_hasarray = usedRange. int[] arr_size = new int[2]; arr_size[0] = arr_formulas.GetLength(0); arr_size[1] = arr_formulas.GetLength(1); string end_address = Tools.NextCell(start_address, arr_size[0] - 1, arr_size[1] - 1); ConcurrentBag <string> hs_arr_exclusion = new ConcurrentBag <string>(); //for each row r in R Parallel.For(1, arr_size[0] + 1, r => { //for (int r = 1; r <= arr_size[0]; r++) //{ //for each column c in C Parallel.For(1, arr_size[1] + 1, c => { //for (int c = 1; c <= arr_size[1]; c++) //{ //if arr_formula is empty and value is null, continue //if ((string)arr_formulas[r, c] == "" && arr_values[r, c] == null) continue; if ((string)arr_formulas[r, c] == "" && arr_values[r, c] == null) { return; } string curr_address = Tools.NextCell(start_address, r - 1, c - 1); //if there is no formula if (!((string)arr_formulas[r, c]).Contains("=")) { //get value type string type = arr_values[r, c].GetType().ToString(); //add to relevant constant dictionary switch (type) { case "System.Double": dict_constants[sh].TryAdd(curr_address, (float)(double)arr_values[r, c]); break; case "System.String": dict_string_constants[sh].TryAdd(curr_address, (string)arr_values[r, c]); break; default: break; } } else //else { //if the cell address is in the exclusion hashset, continue //if (hs_arr_exclusion.Contains(curr_address)) continue; if (hs_arr_exclusion.Contains(curr_address)) { return; } //Excel.Range cell = usedRange.get_Range(curr_address); //if (cell.HasArray) //{ // Excel.Range array_range = cell.CurrentArray; // string first_addr = array_range.Cells[1, 1].Address.Replace("$", ""); // //if the cell is an array formula and it's not the first one, continue // //if (curr_address != first_addr) continue; // if (curr_address != first_addr) return; // //else // //calculate the array formula range // Tools.ArrayFormulaInfo afi_temp; // afi_temp.Cols = array_range.Formula.GetLength(1); // afi_temp.Rows = array_range.Formula.GetLength(0); // afi_temp.StartCell = first_addr; // afi_temp.EndCell = Tools.NextCell(first_addr, afi_temp.Rows - 1, afi_temp.Cols - 1); // //add to dictionary // dict_loader_array_formulas[sh].TryAdd(first_addr, afi_temp); // //add to exclusion hashset all the array formula cells // string[] exc_cells = Tools.RangeCells(first_addr, afi_temp.EndCell); // for (int i = 0; i < exc_cells.Length; i++) // hs_arr_exclusion.Add(exc_cells[i]); //} dict_formulas[sh].TryAdd(curr_address, ((string)arr_formulas[r, c]).Replace("=", "")); } }); }); Marshal.ReleaseComObject(usedRange); }); sw.Stop(); Marshal.ReleaseComObject(activeBook); int num_sheets = dict_sheet_name_map.Count; sw.Start(); PipeClient pipe_client = new PipeClient("ijiBearExcelIdeaEXCELSOURCE"); PipeMessage msg = new PipeMessage(); msg.dict_loader_array_formulas = new List <Dictionary <string, Tools.ArrayFormulaInfo> >(num_sheets); msg.dict_loader_array_formulas.AddRange(new Dictionary <string, Tools.ArrayFormulaInfo> [num_sheets]); msg.dict_loader_constants = new List <Dictionary <string, float> >(num_sheets); msg.dict_loader_constants.AddRange(new Dictionary <string, float> [num_sheets]); msg.dict_loader_formulas = new List <Dictionary <string, string> >(num_sheets); msg.dict_loader_formulas.AddRange(new Dictionary <string, string> [num_sheets]); msg.dict_loader_string_constants = new List <Dictionary <string, string> >(num_sheets); msg.dict_loader_string_constants.AddRange(new Dictionary <string, string> [num_sheets]); msg.dict_sheet_name_map = dict_sheet_name_map; for (int i = 0; i < num_sheets; i++) { msg.dict_loader_array_formulas[i] = dict_loader_array_formulas[i].ToDictionary(kvp => kvp.Key, kvp => kvp.Value); msg.dict_loader_constants[i] = dict_constants[i].ToDictionary(kvp => kvp.Key, kvp => kvp.Value); msg.dict_loader_formulas[i] = dict_formulas[i].ToDictionary(kvp => kvp.Key, kvp => kvp.Value); msg.dict_loader_string_constants[i] = dict_string_constants[i].ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } pipe_client.Send(msg); sw.Stop(); }