Tag: task parallel library

在ContinueWith()块中使用await

我有以下代码: var result = MessageBoxHelper.MsgBox .ShowAsync(“Press Yes to proceed”, MessageBoxButton.YesNo) .ContinueWith((answer) => { if (answer.Result == MessageBoxResult.Yes) { Task asyncTask = ExecuteAsyncFunc(); //asyncTask.Unwrap(); ?? asyncTask.ContinueWith((a) => { // More }, TaskContinuationOptions.OnlyOnRanToCompletion); } }, TaskContinuationOptions.OnlyOnRanToCompletion); } 像这样在其他地方调用: public async Task ExecuteAsyncFunc() { await CallAnotherAsyncFunction(); } 我相信我需要调用Unwrap(),我试过,因为我在ContinueWith()块中调用await。 但是,当我取消注释时,我收到以下错误: 错误CS1929’Task’不包含’Unwrap’的定义,最好的扩展方法重载’TaskExtensions.Unwrap(Task)’需要’Task’类型的接收器 我是否需要在此上下文中使用Unwrap,如果是这样,我做错了什么?

这是.NET 4.5的WhenAll的正确.NET 4实现吗?

我正在使用SignalR。 Hub上的function通常返回一个Task。 我现在有一个函数可以添加一组连接。 我想返回一个代表所有这些任务的Task。 我找到了一个完美的function:Task.WhenAll。 然而,这是.NET 4.5中的一项新function,我仍然坚持使用.NET 4。 因此,我决定编写自己的版本,直到我们可以转到.NET 4.5。 因为在涉及multithreading时经常有一些警告(例如线程池的东西),我不确定我的实现是否正确: public static Task WhenAll(IEnumerable tasks) { return Task.Factory.StartNew(() => Task.WaitAll(tasks.ToArray())); } 在function上,我认为它可行,但是我不会为新任务获得额外的阻塞线程吗? 或者这是不可避免的? 编辑:以下是我将如何与SignalR一起使用: public static Task Add(this IGroupManager groupManager, string connectionId, IEnumerable groups) { return WhenAll(groups.Select(group => groupManager.Add(connectionId, group))); }

如何在后台运行非必要的计算?

这个问题是为什么这个代码同步运行? 。 我意识到我的真​​实问题比那篇文章中的问题更高。 我现在要问的问题是“我该如何做到这一点?” 我想在C#中使用并发来计算后台的东西。 我有类ptsTin,它代表现有的地面。 我想尽快加载。 有些工作是必不可少的,因为在工作完成之前你没有实例。 例如,直到.LoadPoints()和.LoadTriangles都完成后才会有ptsTin实例。 工作的其他部分不是必需的,可以在以后计算,即使以后是0.2秒。 我想在一个新的线程中开始非必要的工作而忘记它。 如果它正在处理的值尚未就绪,则该值将为null。 所以这就是我想做的事情。 代码现在位于控制台应用程序中,但有一天会在GUI应用程序中。 注意,这是伪代码 。 我知道它不会像这样工作,它的目的是传达我想知道如何做的事情: static void Main(string[] args) { var myTin = ptsDTM.Load(“SomeFile.ptsTin”); // Do other stuff here like getElevationAtAPoint(); } public static ptsTin Load(String file) { // Essential Work ptsTin newTin = new ptsTin(); newTin.LoadPoints(file); newTin.LoadTriangles(file); // At this point I […]

为什么这个C#数据处理应用程序的吞吐量远低于服务器的原始function?

我已经整理了一个小的测试工具来诊断为什么我的C#数据处理应用程序的吞吐量(它的核心function使用非阻塞IO从远程数据库服务器批量选择100个记录并对它们执行简单处理)远低于它可能是。 我观察到,在运行时,应用程序不会遇到CPU(<3%),网络或磁盘IO或RAM方面的瓶颈,并且不会对数据库服务器造成压力(数据库上的数据集几乎总是完全在内存)。 如果我并行运行应用程序的多个实例,我可以达到~45个实例,延迟仅降低约10%但吞吐量增加45倍,然后数据库服务器上的CPU利用率成为瓶颈(此时,那里仍然没有客户端的资源瓶颈)。 我的问题是,当客户端服务器能够大幅提高吞吐量时,为什么TPL不增加飞行中的任务数量或以其他方式增加吞吐量? 简化代码摘录: public static async Task ProcessRecordsAsync() { int max = 10000; var s = new Stopwatch(); s.Start(); Parallel.For(0, max, async x => { await ProcessFunc(); }); s.Stop(); Console.WriteLine(“{2} Selects completed in {0} ms ({1} per ms).”, s.ElapsedMilliseconds, ((float)s.ElapsedMilliseconds) / max, max); } public static async Task ProcessFunc() { string sql = […]

如何使用委托构造TransformManyBlock

我是C#TPL和DataFlow的新手,我正在努力研究如何实现TPL DataFlow TransformManyBlock 。 我正在将其他一些代码翻译成DataFlow。 我的(简化)原始代码是这样的: private IEnumerable ExtractFromByteStream(Byte[] byteStream) { yield return byteStream; // Plus operations on the array } 在另一种方法中,我会这样称呼它: foreach (byte[] myByteArray in ExtractFromByteStream(byteStream)) { // Do stuff with myByteArray } 我正在尝试创建一个TransformManyBlock来生成来自较大输入数组(实际上是二进制流)的多个小数组(实际上是数据包),因此in和out都是byte[]类型。 我尝试了下面的内容,但我知道我错了。 我想使用与之前相同的函数构造此块,并将TransformManyBlock包装在其周围。 我收到一个错误“电话不明确……” var streamTransformManyBlock = new TransformManyBlock(ExtractFromByteStream);

我应该将任务包装在另一个任务中,还是应该只返回创建的任务?

我正在构建一个使用ADO.NET的.NET 4.0应用程序,所以我不能使用async / await。 我不想要一个解决方案,但我想知道以下哪些实现最好,为什么。 我的unit testing通过所有三个实现,但我想知道这三个之间的区别。 #1嵌套任务 在我的第一个实现中,我将任务包装在另一个任务中。 我认为搞两个任务对性能不利,但我不确定。 public virtual Task ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken) { return Task.Factory.StartNew(() => { var sqlCommand = CheckIfSqlCommand(dbCommand); PrepareExecuteReader(dbCommand); return Task .Factory .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null) .Result; }, cancellationToken); } #2使用TaskCompletionSource 然后我尝试将结果包装在TaskCompletionSource所以我只有一个任务。 public virtual Task ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken) { var taskCompletionSource = new TaskCompletionSource(); var sqlCommand = […]

如何在不阻止UI线程的情况下继续执行多个任务?

在我的MVVM应用程序中,我的视图模型调用3种不同的服务方法,将每种数据转换为通用格式,然后使用属性通知/可观察集合等更新UI。 服务层中的每个方法都会启动一个新Task ,并将Task返回给视图模型。 这是我的一种服务方法的示例。 public class ResourceService { internal static Task LoadResources(Action<IEnumerable> completedCallback, Action errorCallback) { var t = Task.Factory.StartNew(() => { //… get resources from somewhere return resources; }); t.ContinueWith(task => { if (task.IsFaulted) { errorCallback(task.Exception); return; } completedCallback(task.Result); }, TaskScheduler.FromCurrentSynchronizationContext()); return t; } } 这是调用代码和视图模型的其他相关部分…… private ObservableCollection Data = new ObservableCollection(); public ICollectionView […]

使用ContinueWith作为“最终”操作是否安全?

考虑一段代码,如: private Task Download() { var wc = new WebClient(); Task backgroundDownload = wc.DownloadStringTaskAsync(this.Uri); // Make sure the WebClient is disposed no matter what. backgroundDownload.ContinueWith((downloadTask) => { wc.Dispose(); }); return backgroundDownload; } 我可以确定WebClient.Dispose()调用是否会发生,并且生成的任何exception都会重新抛出给调用者,就好像没有调用ContinueWith ? 客户可以观察到这个ContinueWith吗? (例如稍后会调用ContinueWith删除Dispose调用吗?)

.NET4中未观察到的任务exception

根据一些文章和博客,像下面这样的代码应该导致.NET 4中的exception static void Main(string[] args) { Task.Factory.StartNew(() => { throw new Exception(); }); Thread.Sleep(1000); GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine(“Completed”); } 预期例外: 未处理的exception:System.AggregateException:通过等待任务或访问其Exception属性未观察到任务的exception。 结果,终结器线程重新抛出了未观察到的exception。 —> System.InvalidOperationException:由于对象的当前状态,操作无效。 但它并没有。 我的PC上的.NET 4应用程序就像.NET 4.5一样: 默认情况下,他们不会抛出该聚合exception 他们在配置文件中检测到以下设置: 看起来.NET 4已被修补以获得与.NET 4.5相同的行为。 它是真的还是我的配置有些麻烦? 或者,如果安装了4.5,任何.NET4应用程序(不是以4.5为目标)的行为都会如此? 提前致谢。

C#中的异步方法不是异步的吗?

创建了以下控制台应用程序后,我有点困惑为什么它似乎同步运行而不是异步运行: class Program { static void Main(string[] args) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var total = CreateMultipleTasks(); stopwatch.Stop(); Console.WriteLine(“Total jobs done: {0} ms”, total.Result); Console.WriteLine(“Jobs done in: {0} ms”, stopwatch.ElapsedMilliseconds); } static async Task CreateMultipleTasks() { var task1 = WaitForMeAsync(5000); var task2 = WaitForMeAsync(3000); var task3 = WaitForMeAsync(4000); var val1 = await task1; […]