Tag: 任务 并行库

取消任务

如果等待时间结束,我有一个需要取消的任务。 例如 var t = Task.Factory.StartNew(() => { Thread.Sleep(5000) // some long running task “do something” }); Task.WaitAll(new[] {t}, 1000); 但似乎任务仍在继续。 我尝试使用CancellationTokenSource,但似乎也没有用。 我使用以下代码段确认了这一点 static void Main(string[] args) { var cancellationTokenSource = new CancellationTokenSource(); var t = Task.Factory.StartNew(() => { Thread.Sleep(5000); Console.WriteLine(“Still working”); }, cancellationTokenSource.Token); Task.WaitAll(new[] {t}, 1000); cancellationTokenSource.Cancel(); Console.ReadLine(); } 控制台显示“仍在工作”。 我以为任务会被取消。 我相信我错过了一些东西。 我错过了什么? 谢谢。

Task.ContinueWith捕获调用线程上下文以继续吗?

下面的Test_Click是在UI线程(使用WindowsFormsSynchronizationContext )上运行的代码的简化版本: void Test_Click(object sender, EventArgs e) { var task = DoNavigationAsync(); task.ContinueWith((t) => { MessageBox.Show(“Navigation done!”); }, TaskScheduler.FromCurrentSynchronizationContext()); } 我应该显式指定TaskScheduler.FromCurrentSynchronizationContext()以确保将在同一UI线程上执行继续操作吗? 或者ContinueWith自动捕获执行上下文(因此,在这种情况下使TaskScheduler参数成为冗余)? 我认为默认情况下不会这样做(不像await ),但到目前为止我找不到在线资源来确认这一点。

可以从TPL任务派生从方法返回更多细节吗?

我的原始方法如下: string DoSomeWork(); 方法DoSomeWork在其他线程上启动一些工作并返回执行ID(只是随机字符串)。 稍后我可以通过给定的执行ID查询结果。 重点是在作业完成之前使执行ID可用。 现在我想更改签名以返回Task,因此用户可以等待。 Task DoSomeWork(); 同时我仍然需要返回执行ID(例如用于跟踪),我看到几个选项。 首先,如果out参数,第二个是返回带有执行ID和任务的元组(在C#中,这看起来不是最佳选项),第三个是我实际想要问的。 如果我将创建将派生自Task类的类,该怎么办: public class ExtendedTask : Task { public string ExecutionID {get; set;} } 这看起来不错吗? 或者最好决定其他选择? PS在BCL中有一些派生自Task类。 更新 ,似乎我无法定义这个明确的enouthg。 但是我需要在作业完成之前访问ExecutionID,因此我不能使用Task.Result 。

重新访问异步void方法的用例

我知道最好的做法是避免除异步事件处理程序之外的任何async void方法,并且对其他用例有很强的专家意见 。 然而,我只是参与了关于async void方法的有用性的简短讨论 ,我有几个问题: 框架如何跟踪挂起的async void方法,包括事件处理程序? 有没有办法获取它们的当前列表或取消它们( 编辑 :可能通过安装自定义SynchronizationContext跟踪)? 它们对火灾和遗忘记录有用吗? 我认为它们实际上可能是,只要在方法开始时保留了正确的时间戳,它仍然可以同步执行。

TPL完成与完成

我需要从遗留数据库导入客户相关数据,并在此过程中执行多次转换。 这意味着单个条目需要执行其他“事件”(同步产品,创建发​​票等)。 我最初的解决方案是简单的并行方法。 它工作正常,但有时它有问题。 如果当前处理的客户需要等待相同类型的事件,他们的处理队列可能会卡住并最终超时,导致每个基础事件也失败(它们依赖于失败的事件)。 它不会一直发生,但它很烦人。 所以我有了另一个想法,分批工作。 我的意思不仅是限制同时处理的客户数量,还包括广播到队列的事件数量。 在寻找想法时,我找到了这个答案,它指向了TPL DataFlow 。 我制作了一个骨架来熟悉它。 我建立了一个简单的管道,但我对Complete()的使用和等待Completion()有点困惑。 步骤如下 制作一个数字列表(要导入的客户的ID) – 这是在导入逻辑之外,它只是在那里能够触发其余的逻辑 创建BatchBlock (以便能够同时限制要处理的客户数量) 基于id创建单个MyClass1项( TransformBlock ) 执行一些逻辑并生成MyClass2的集合( TransformManyBlock ) – 例如,睡眠1秒 对集合的每个项目执行一些逻辑( ActionBlock ) – 例如,hibernate1秒钟 这是完整的代码: public static class Program { private static void Main(string[] args) { var batchBlock = new BatchBlock(2); for (var i = 1; i […]

如何强制取消任务?

假设,有一项任务包含以下约: Task someTask = new Task(() => { while(!IsCancellationRequested) { Do_something_over_a_long_period_of_time(); token.ThrowIfCancellationRequested(); Do_something_over_a_long_period_of_time(); token.ThrowIfCancellationRequested(); Do_something_over_a_long_period_of_time(); token.ThrowIfCancellationRequested(); } }); someTask.Start(); 并且有非常不耐烦的用户。 他们渴望立即终止我的申请。 他们不想等待长时间的行动。 我曾经使用Thread类,并能够通过调用Abort()命令立即中止我的所有线程。 我如何立即中止我的任务? 谢谢。

取消长时间运行任务后如何正确清理

我创建了一个类,其目的是抽象出对队列的并发访问的控制。 该类被设计为在单个线程上实例化,由多个线程写入,然后从后续单个线程读取。 我在类中生成了一个长时间运行的任务,它将执行阻塞循环并在项成功出列时触发事件。 我的问题是:我执行取消长时间运行的任务并随后清理/重置CancellationTokenSource对象的正确用法吗? 理想情况下,我希望能够在保持可用性以添加到队列的同时停止并重新启动活动对象。 我用Peter Bromberg的文章作为基础: C#4.0中的生产者/消费者队列和BlockingCollection 代码如下: using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; namespace Test { public delegate void DeliverNextQueuedItemHandler(T item); public sealed class SOQueueManagerT { ConcurrentQueue _multiQueue; BlockingCollection _queue; CancellationTokenSource _canceller; Task _listener = null; public event DeliverNextQueuedItemHandler OnNextItem; public bool IsRunning { get; private set; } public int QueueSize […]

通过更改值传递参数到任务 – 行为?

场景:循环中的异步任务执行一个方法,该方法包含随程序继续而变化的参数: while(this._variable { aList.add(this._variable); update(this._savePoint); }); } 如果循环比任务完成的运行得快,列表是否会添加变量的当前值,还是本地保存的变量并添加原始值?

等待Task.Run(()=> semaphore.WaitOne())有什么问题吗?

标题说明了一切。 await Task.Run(() => semaphore.WaitOne());有什么问题await Task.Run(() => semaphore.WaitOne()); ? System.Threading.Semaphore不是线程仿射的,所以我不认为会有问题。 我知道SemaphoreSlim类是可用的,但我需要进行跨进程同步,而SemaphoreSlim不会这样做。 或者我可以/应该创建自己的自定义类型的WaitHandle吗?

CancellationToken.ThrowIfCancellationRequested后出现故障与已取消的任务状态

通常我不回答问题,但这次我想引起一些关注,我认为这可能是一个模糊而又常见的问题。 它是由这个问题触发的,从那时起我查看了我自己的旧代码,发现其中一些也受到了影响。 下面的代码启动并等待两个任务, task1和task2 ,几乎完全相同。 task1与task2不同之处在于它运行永无止境的循环。 对于执行CPU限制工作的一些现实场景,这两种情况都非常典型。 using System; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication { public class Program { static async Task TestAsync() { var ct = new CancellationTokenSource(millisecondsDelay: 1000); var token = ct.Token; // start task1 var task1 = Task.Run(() => { for (var i = 0; ; i++) { Thread.Sleep(i); // simulate […]