public static R BuildandWaitResult <R, P>(P groupTpWaiterParams, string methodName
                                                  , Action <string> onError, Action <double> incProgress = null
                                                  , CancellationToken?cancellationToken = null, Action <bool> setIndeterminat = null
                                                  )
            where R : class //Тип для результата
            where P : class //Тип для параметров
        {
            ProtoInitializer.InitProtobuf();

            int voidPacketLimit;

            var setting = EnumClientServiceDictionary.GetGlobalSettingsByName(RegistrySettings.FolderVisual, RegistrySettings.SettingVoidPacketLimit);

            if (setting == null || setting.Setting == null || !int.TryParse(setting.Setting, out voidPacketLimit) ||
                voidPacketLimit < 10) //Максимальное количество не ограничиваем
            {
                voidPacketLimit = 24001;
            }

            Guid loaderId;

            try
            {
                MemoryStream compressedParam;
                using (var ms = new MemoryStream())
                {
                    ProtoBuf.Serializer.Serialize(ms, groupTpWaiterParams);
                    ms.Position     = 0;
                    compressedParam = CompressUtility.CompressGZip(ms);
                }

                compressedParam.Position = 0;
                loaderId = ARM_Service.Builder_StartWait(compressedParam, methodName);
                Thread.Sleep(100);
            }
            catch (Exception ex)
            {
                if (onError != null)
                {
                    onError("Ошибка запуска построителя фак. мощности: " + ex.Message);
                }
                return(null);
            }

            var isLastPacket  = false;
            var voidCounter   = 0;
            var errCounter    = 0;
            var requestNumber = 0;
            var ca            = new List <byte>();

            var packetSize = 0.0; //Тут надо подумать как возвращать правильный размер, возможно никак

            do
            {
                if (cancellationToken.HasValue && cancellationToken.Value.IsCancellationRequested)
                {
                    ARM_Service.Builder_Cancel(loaderId);
                    break; //Отмена выполнения
                }

                try
                {
                    var packet = ServiceFactory.ArmServiceInvokeSync <BuilderPartResult>("Builder_GetNextPart", requestNumber, loaderId);
                    if (packet != null)
                    {
                        if (!string.IsNullOrEmpty(packet.Errors))
                        {
                            //Это критическая ошибка, продолжать нельзя
                            if (onError != null)
                            {
                                onError(packet.Errors);
                            }
                            break;
                        }

                        isLastPacket = packet.IsLastPacket;
                        if (isLastPacket)
                        {
                            break;
                        }

                        if (packet.Part != null && packet.Part.Length > 0)
                        {
                            //requestNumber++;
                            if (requestNumber == 0)
                            {
                                if (packet.PacketRemaining == 0)
                                {
                                    packetSize = 1;
                                }
                                else
                                {
                                    packetSize = 100 / (double)packet.PacketRemaining;
                                }

                                if (setIndeterminat != null)
                                {
                                    setIndeterminat(false);
                                }
                            }

                            ca.InsertRange(0, packet.Part.ToArray());
                            requestNumber++;

                            packet.Part.Close();
                            packet.Part.Dispose();

                            voidCounter = 0;

                            Thread.Sleep(10);
                        }
                        else
                        {
                            if (++voidCounter > voidPacketLimit)
                            {
                                isLastPacket = true;
                                if (onError != null)
                                {
                                    onError("ClientSideMultithreadBuilder: Превышен лимит ожидания пакетов");
                                }
                            }
                            else
                            {
                                Thread.Sleep(300);
                            }
                        }

                        errCounter = 0;
                    }
                    else
                    {
                        if (++errCounter > 50)
                        {
                            isLastPacket = true;
                            if (onError != null)
                            {
                                onError("ClientSideMultithreadBuilder: Превышен лимит пустых пакетов");
                            }
                        }

                        Thread.Sleep(5000);
                    }
                }
                catch (Exception ex)
                {
                    if (++errCounter > 6)
                    {
                        isLastPacket = true;
                        if (onError != null)
                        {
                            onError("ClientSideMultithreadBuilder: Сервер не отвечает");
                        }
                    }
                    else
                    {
                        if (onError != null)
                        {
                            onError(ex.Message);
                        }
                        Thread.Sleep(5000);
                    }
                }

                if (incProgress != null)
                {
                    incProgress(packetSize);
                }
            } while (!isLastPacket);

            var compressed = new MemoryStream(ca.ToArray());

            ca = null;

            R result = null;

            if (compressed.Length > 2)
            {
                try
                {
                    using (var ms = CompressUtility.DecompressGZip(compressed))
                    {
                        compressed.Close();
                        compressed.Dispose();

                        ms.Position = 0;
                        result      = ProtoBuf.Serializer.Deserialize <R>(ms);
                    }
                }
                catch (Exception ex)
                {
                    if (onError != null)
                    {
                        onError("ClientSideMultithreadBuilder: Ошибка обработки результата: " + ex.Message);
                    }
                }
            }

            GC.Collect();

            return(result);
        }
예제 #2
0
        public static BalanceFreeHierarchyResults BL_GetFreeHierarchyBalanceResult(List <string> balanceFreeHierarchyUNs, DateTime dTStart, DateTime dTEnd, string timeZoneId,
                                                                                   TExportExcelAdapterType adapterType, bool isGenerateDoc, enumTimeDiscreteType discreteType,
                                                                                   EnumUnitDigit unitDigit, bool isFormingSeparateList, EnumUnitDigit unitDigitIntegrals, bool isUseThousandKVt, bool printLandscape, byte doublePrecisionProfile, byte doublePrecisionIntegral,
                                                                                   bool need0, bool isAnalisIntegral, bool setPercisionAsDisplayed, CancellationToken?cancellationToken = null)
        {
            var balance = new BalanceFreeHierarchyResults(balanceFreeHierarchyUNs, dTStart, dTEnd, timeZoneId, adapterType, isGenerateDoc,
                                                          discreteType, unitDigit, unitDigitIntegrals, cancellationToken);

            if (cancellationToken.HasValue && cancellationToken.Value.IsCancellationRequested)
            {
                return(balance);
            }

            if (isGenerateDoc)
            {
                string branchName;
                //Читаем подписантов
                var signaturesByBalance = GetBalanceSignatures(balanceFreeHierarchyUNs, out branchName);

                var po = new ParallelOptions();
                if (cancellationToken.HasValue)
                {
                    po.CancellationToken = cancellationToken.Value;
                }

                po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
                po.CancellationToken.ThrowIfCancellationRequested();

                using (var adapter = new ExcelReportFreeHierarchyAdapter(balance, signaturesByBalance, adapterType, balance.Errors,
                                                                         isFormingSeparateList, isUseThousandKVt, printLandscape, branchName,
                                                                         doublePrecisionProfile, doublePrecisionIntegral, need0, isAnalisIntegral, timeZoneId, setPercisionAsDisplayed))
                {
                    Parallel.ForEach(balanceFreeHierarchyUNs, po, (balanceUn, loopState) =>
                    {
                        BalanceFreeHierarchyCalculatedResult calculatedValue;
                        if (!balance.CalculatedValues.TryGetValue(balanceUn, out calculatedValue))
                        {
                            return;
                        }

                        //Формирование документов по каждому балансу
                        try
                        {
                            if (po.CancellationToken.IsCancellationRequested)
                            {
                                loopState.Break();
                            }

                            calculatedValue.CompressedDoc = CompressUtility.CompressGZip(adapter.BuildBalanceFreeHier(calculatedValue));
                        }
                        catch (Exception ex)
                        {
                            lock (balance.Errors)
                            {
                                balance.Errors.Append("Ошибка генерации документа - " + ex.Message);
                            }
                        }
                    });
                }
            }

            return(balance);
        }