public unsafe void Test_ParallelHelper_ForEach_In2D( int sizeY, int sizeX, int row, int column, int height, int width) { int[,] data = CreateRandomData2D(sizeY, sizeX); // Create a memory wrapping the random array with the given parameters ReadOnlyMemory2D <int> memory = data.AsMemory2D(row, column, height, width); Assert.AreEqual(memory.Length, height * width); Assert.AreEqual(memory.Height, height); Assert.AreEqual(memory.Width, width); int sum = 0; // Sum all the items in parallel. The Summer type takes a pointer to a target value // and adds values to it in a thread-safe manner (with an interlocked add). ParallelHelper.ForEach(memory, new Summer(&sum)); int expected = 0; // Calculate the sum iteratively as a baseline for comparison foreach (int n in memory.Span) { expected += n; } Assert.AreEqual(sum, expected, $"The sum doesn't match, was {sum} instead of {expected}"); }
public void Test_ParallelHelper_ForEach_Ref() { foreach (int count in TestForCounts) { using UnmanagedSpanOwner <int> data = CreateRandomData(count); using UnmanagedSpanOwner <int> copy = new UnmanagedSpanOwner <int>(count); data.GetSpan().CopyTo(copy.GetSpan()); foreach (ref int n in copy.GetSpan()) { n = unchecked (n * 397); } ParallelHelper.ForEach(data.Memory, new Multiplier(397)); Span <int> dataSpan = data.GetSpan(); Span <int> copySpan = copy.GetSpan(); for (int i = 0; i < data.Length; i++) { if (dataSpan[i] != copySpan[i]) { Assert.Fail($"Item #{i} was not a match, was {dataSpan[i]} instead of {copySpan[i]}"); } } } }
public void Test_ParallelHelper_ForEach_Ref2D( int sizeY, int sizeX, int row, int column, int height, int width) { int[,] data = CreateRandomData2D(sizeY, sizeX), copy = (int[, ])data.Clone(); // Prepare the target data iteratively foreach (ref int n in copy.AsSpan2D(row, column, height, width)) { n = unchecked (n * 397); } Memory2D <int> memory = data.AsMemory2D(row, column, height, width); Assert.AreEqual(memory.Length, height * width); Assert.AreEqual(memory.Height, height); Assert.AreEqual(memory.Width, width); // Do the same computation in paralellel, then compare the two arrays ParallelHelper.ForEach(memory, new Multiplier(397)); CollectionAssert.AreEqual(data, copy); }
/// <summary> /// Imports the tracks. /// </summary> /// <param name="externalFolder">The external folder.</param> public void ImportExternalShufflerTracks(string externalFolder) { var files = FileSystemHelper.SearchFiles(externalFolder, "*.mp3", true); ParallelHelper.ForEach(files, file => { ImportExternalShufflerTrack(file, externalFolder); }); SaveToDatabase(); }
public void LoadFromFiles() { lock (_samples) { _samples.Clear(); } var files = FileSystemHelper.SearchFiles(_folder, "*.wav", true); ParallelHelper.ForEach(files, LoadSample); }
private void ExportSamples(List <Sample> samples) { StopSamples(); Cursor = Cursors.WaitCursor; var folder = FileDialogHelper.OpenFolder(); if (folder == "") { return; } ParallelHelper.ForEach(samples, sample => { var track = SampleLibrary.GetTrackFromSample(sample); if (track == null) { return; } var outPath = Path.Combine(folder, track.Genre); if (!Directory.Exists(outPath)) { Directory.CreateDirectory(outPath); } var outFile = FileSystemHelper.StripInvalidFileNameChars($"{sample.Bpm:000.00} - {sample.TrackArtist} - {sample.TrackTitle} - {sample.Description}.wav"); outPath = Path.Combine(outPath, outFile); if (File.Exists(outPath)) { File.Delete(outPath); } AudioExportHelper.SavePartialAsWave(track.Filename, outPath, sample.Start, sample.Length, sample.Offset, sample.Gain); }); Cursor = Cursors.Default; }
public unsafe void Test_ParallelHelper_ForEach_In() { foreach (int count in TestForCounts) { using UnmanagedSpanOwner <int> data = CreateRandomData(count); int sum = 0; ParallelHelper.ForEach <int, Summer>(data.Memory, new Summer(&sum)); int expected = 0; foreach (int n in data.GetSpan()) { expected += n; } Assert.AreEqual(sum, expected, $"The sum doesn't match, was {sum} instead of {expected}"); } }
/// <summary> /// Imports the tracks. /// </summary> /// <param name="folder">The folder.</param> public void ImportTracks(string folder) { if (folder == "") { folder = LibraryFolder; } if (!folder.StartsWith(LibraryFolder)) { return; } _cancelImport = false; var files = FileSystemHelper.SearchFiles(folder, "*.mp3", true); // remove tracks that don't exist in file system var currentTracks = Tracks.Where(t => t.Filename.StartsWith(folder)).ToList(); var missingTracks = currentTracks.TakeWhile(track => !_cancelImport) .Where(track => !files.Contains(track.Filename)) .ToList(); lock (Tracks) { foreach (var track in missingTracks.TakeWhile(track => !_cancelImport)) { Tracks.Remove(track); if (_cancelImport) { break; } } } ParallelHelper.ForEach(files.TakeWhile(file => !_cancelImport), file => { LoadTrack(file); }); SaveToDatabase(); }
public void Test_ParallelHelper_ForEach_Ref() { foreach (int count in TestForCounts) { int[] data = CreateRandomData(count); int[] copy = data.AsSpan().ToArray(); foreach (ref int n in copy.AsSpan()) { n = unchecked (n * 397); } ParallelHelper.ForEach(data.AsMemory(), new Multiplier(397)); for (int i = 0; i < data.Length; i++) { if (data[i] != copy[i]) { Assert.Fail($"Item #{i} was not a match, was {data[i]} instead of {copy[i]}"); } } } }
public async Task <IDTOperationRecordPollingRollbackController> Execute(string storeGroupName, string memberName) { //获取存储组 var storeGroup = await _storeGroupRepositoryCacheProxy.QueryByName(storeGroupName); if (storeGroup == null) { var fragment = new TextFragment() { Code = TextCodes.NotFounStoreGroupMemberByName, DefaultFormatting = "找不到名称为{0}的存储组", ReplaceParameters = new List <object>() { storeGroupName } }; throw new UtilityException((int)Errors.NotFounStoreGroupByName, fragment); } //获取指定的组成员 var groupMember = await storeGroup.GetMember(memberName); if (groupMember == null) { var fragment = new TextFragment() { Code = TextCodes.NotFoundStoreGroupMemberInGroup, DefaultFormatting = "在名称为{0}的存储组下找不到名称为{1}的成员", ReplaceParameters = new List <object>() { storeGroupName, memberName } }; throw new UtilityException((int)Errors.NotFoundStoreGroupMemberInGroup, fragment); } var pollingResult = await PollingHelper.Polling <DTOperationRecord>( async() => { await Task.CompletedTask; return (new AsyncInteration <DTOperationRecord> ( async(index) => { if (index == 0) { while (true) { var completeList = await _dtOperationRecordRepository.QueryBySkip(groupMember.StoreInfo, (int)DTOperationRecordStatus.Complete, 0, 500); await ParallelHelper.ForEach(completeList, 5, async(record) => { await record.Delete(); } ); if (completeList.Count < 500) { break; } } } var datas = await _dtOperationRecordRepository.QueryBySkip(groupMember.StoreInfo, (int)DTOperationRecordStatus.UnComplete, index * 500, 500); return datas; } )); }, 5, 500, async(record) => { try { using (var diContainer = DIContainerContainer.CreateContainer()) { var orginialDI = ContextContainer.GetValue <IDIContainer>("DI"); try { ContextContainer.SetValue <IDIContainer>("DI", diContainer); if (await record.NeedCancel()) { await record.Cancel(); } } finally { ContextContainer.SetValue <IDIContainer>("DI", orginialDI); } } } catch (Exception ex) { Exception rootEx = ex; while (ex.InnerException != null) { ex = ex.InnerException; } if (ex != rootEx) { await record.UpdateErrorMessage($"root message:{rootEx.Message},inner message:{ex.Message},root Stack:{rootEx.StackTrace},inner Stack:{ex.StackTrace}"); } else { await record.UpdateErrorMessage($"message:{rootEx.Message},Stack:{rootEx.StackTrace}"); } } }, null, async(ex) => { LoggerHelper.LogError(ErrorLoggerCategoryName, $"DTOperationRecordPollingRollbackService Execute Error,ErrorMessage:{ex.Message},StackTrace:{ex.StackTrace}"); } ); DTOperationRecordPollingRollbackControllerDefault controller = new DTOperationRecordPollingRollbackControllerDefault(pollingResult); return(controller); }
public async Task <object> Calcualte(ExpressionCalculator calculator, string expression, object executeContext) { if (string.IsNullOrEmpty(expression)) { var fragment = new TextFragment() { Code = TextCodes.ExpressionEmptyInExpressionCalculatorByName, DefaultFormatting = "在名称为{0}的表达式计算器中,要计算的表达式为空", ReplaceParameters = new List <object>() { calculator.Name } }; throw new UtilityException((int)Errors.ExpressionEmptyInExpressionCalculatorByName, fragment); } //公式的正则表达式 Regex reg = new Regex(@"\{(?<!\\)\$[A-Za-z0-9]((?!(\{(?<!\\)\$[A-Za-z0-9][A-Za-z0-9_]+\(.*\)(?<!\\)\})).)+?(?<!\\)\}"); //公式参数_ref的正则表达式 Regex regRefExpression = new Regex(@"(?<!\\)\$_ref\((.*)\)"); ///公式参数_ref的参数的正则表达式 //Regex regRefParameterExpression = new Regex(@"(?<=\$_ref\().*(?=\))"); ConcurrentDictionary <string, object> dictValues = new ConcurrentDictionary <string, object>(); while (true) { //通过正则表达式获取公式参数 var matchs = reg.Matches(expression); int length = matchs.Count; if (length == 0) { break; } var matchList = matchs.Cast <Match>(); ConcurrentDictionary <int, string> dictResult = new ConcurrentDictionary <int, string>(); Dictionary <string, Semaphore> lockObjs = new Dictionary <string, Semaphore>(); if (calculator.FormulaExecuteParallelism > 1) { //生成锁定对象集 foreach (var item in matchList) { lockObjs[item.Value] = new Semaphore(1, 1); } } //设定并行计算 await ParallelHelper.ForEach <Match>(matchList, calculator.FormulaExecuteParallelism, async (match) => { //获取公式 var formula = getFormulaCalculator(calculator, match.Value); var formulaService = getFormulaCalculateService(calculator.Name, formula.Name); //检查公式参数,如果参数格式为$_ref(XXX),则值从dictValues中获取, //如果为一般字符串,则需调用对应公式服务的ParameterConvert方法来获取实际值 List <object> formulaParameters = new List <object>(); for (var index = 0; index <= formula.ParameterExpressions.Count - 1; index++) { var peMatch = regRefExpression.Match(formula.ParameterExpressions[index]); if (peMatch.Success) { if (!dictValues.TryGetValue(peMatch.Groups[1].Value, out object pValue)) { var fragment = new TextFragment() { Code = TextCodes.NotFoundValueInExpressionStoreValues, DefaultFormatting = "在名称为{0}的表达式计算器中,找不到键为{1}的值,表达式为{2}", ReplaceParameters = new List <object>() { calculator.Name, peMatch.Groups[1].Value, peMatch.Value } }; throw new UtilityException((int)Errors.NotFoundValueInExpressionStoreValues, fragment); } formulaParameters.Add(pValue); } else { formulaParameters.Add(await formulaService.ParameterConvert(index, formula.ParameterExpressions[index].Replace(@"\}", "}").Replace(@"\$", "$").Replace(@"\,", ",").Replace(@"\\", @"\"))); } } //判断是否可重复使用 //如果可重复使用,则通过公式名称存储 //如果不可重复使用,则通过guid作为名称存储 if (await formulaService.IsIndividual()) { if (!dictValues.TryGetValue(formula.Name, out object value)) { try { if (calculator.FormulaExecuteParallelism > 1) { lockObjs[match.Value].WaitOne(); } if (!dictValues.TryGetValue(formula.Name, out value)) { //计算公式 var formulaValue = await formulaService.Calculate(formulaParameters, executeContext); dictValues[formula.Name] = formulaValue; } } finally { if (calculator.FormulaExecuteParallelism > 1) { lockObjs[match.Value].Release(); } } } dictResult[match.Index] = string.Format(@"$_ref({0})", formula.Name); } else { //计算公式 var formulaValue = await formulaService.Calculate(formulaParameters, executeContext); string calculatedFormulaName = Guid.NewGuid().ToString(); dictValues[calculatedFormulaName] = formulaValue; dictResult[match.Index] = string.Format(@"$_ref({0})", calculatedFormulaName); } }); //为每个匹配项做替换 expression = reg.Replace(expression, (match) => { if (dictResult.TryGetValue(match.Index, out string matchResult)) { return(matchResult); } else { return(match.Value); } }); } //content = content.Replace(@"\}", "}").Replace(@"\$", "$").Replace(@"\,", ",").Replace(@"\\", @"\"); var lastMatch = regRefExpression.Match(expression); if (!lastMatch.Success) { var fragment = new TextFragment() { Code = TextCodes.ExpressionFormatError, DefaultFormatting = "在名称为{0}的表达式计算器中,表达式格式不正确,表达式为{1}", ReplaceParameters = new List <object>() { calculator.Name, expression } }; throw new UtilityException((int)Errors.ExpressionFormatError, fragment); } if (!dictValues.TryGetValue(lastMatch.Groups[1].Value, out object value)) { var fragment = new TextFragment() { Code = TextCodes.NotFoundValueInExpressionStoreValues, DefaultFormatting = "在名称为{0}的表达式计算器中,找不到键为{1}的值,表达式为{2}", ReplaceParameters = new List <object>() { calculator.Name, lastMatch.Groups[1].Value, expression } }; throw new UtilityException((int)Errors.NotFoundValueInExpressionStoreValues, fragment); } return(value); }
public async Task <string> Convert(string content, TemplateContext context) { if (string.IsNullOrEmpty(content)) { return(string.Empty); } while (true) { //通过正则表达式获取标签参数 Regex reg = new Regex(@"\{(?<!\\)\$((?!(\{(?<!\\)\$[A-Za-z0-9_]+\(.*\)(?<!\\)\})).)+?(?<!\\)\}"); var matchs = reg.Matches(content); int length = matchs.Count; if (length == 0) { break; } var matchList = matchs.Cast <Match>(); Dictionary <int, string> dictResult = new Dictionary <int, string>(); Dictionary <string, string> dictLabelResult = new Dictionary <string, string>(); Dictionary <string, SemaphoreSlim> lockObjs = new Dictionary <string, SemaphoreSlim>(); //生成锁定对象集 foreach (var item in matchList) { lockObjs[item.Value] = new SemaphoreSlim(1, 1); } //设定并行计算 await ParallelHelper.ForEach <Match>(matchList, _labelParameterExecuteParallelism, async (match) => { var label = await GetLabel(match.Value); if (label != null) { //检查标签是否时独立标签 if (await label.IsIndividual()) { //独立标签直接计算结果 dictResult.Add(match.Index, await label.Execute(context, label.GetExtension <string[]>(LabelExecuteParameters))); } else { string matchResult; //非独立标签需要复用计算结果 if (!dictLabelResult.TryGetValue(match.Value, out matchResult)) { try { await lockObjs[match.Value].WaitAsync(); if (!dictLabelResult.TryGetValue(match.Value, out matchResult)) { matchResult = await label.Execute(context, label.GetExtension <string[]>(LabelExecuteParameters)); dictLabelResult[match.Value] = matchResult; } } finally { lockObjs[match.Value].Release(); } } dictResult.Add(match.Index, matchResult); } } }); //为每个匹配项做替换 content = reg.Replace(content, (match) => { if (dictResult.TryGetValue(match.Index, out string matchResult)) { return(matchResult); } else { return(match.Value); } }); } content = content.Replace(@"\}", "}").Replace(@"\$", "$").Replace(@"\,", ",").Replace(@"\\", @"\"); return(await Task.FromResult(content)); }