Tag: task parallel library

tpl dataflow:固定缓冲区大小而不丢弃项目

在使用数据流后,我遇到了一个新问题。 我想限制所有块的输入队列。 我的产品块(ActionBlock)正在快速创建5000个元素并将它们发布到广播块。 因此,如果我将广播块的BoundedCapacity设置为100,则会抛出大量数据。 但我更希望生产块等待我的缓冲区输入队列中的新槽。 有没有办法摆脱这个问题?

单声道上的任务并行库实现?

Mono是否实现了Task Parallel库? 如果是这样,.NET和mono之间的性能如何比较。

限制同时执行任务的数量

考虑这个庞大的任务池: var tasks = new Task[4] { Task.Factory.StartNew(() => DoSomething()), Task.Factory.StartNew(() => DoSomething()), Task.Factory.StartNew(() => DoSomething()), Task.Factory.StartNew(() => DoSomething()), Task.Factory.StartNew(() => DoSomething()) }; Task.WaitAll(tasks); 如果我只想同时说3个任务怎么办? 我将如何在代码中实现它?

如何获取不在UI线程上执行的任务

以下代码是实际应用程序中代码的简化。 下面的问题是将在UI线程中运行长时间的工作,而不是后台线程。 void Do() { Debug.Assert(this.Dispatcher.CheckAccess() == true); Task.Factory.StartNew(ShortUIWork, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); } void ShortUIWork() { Debug.Assert(this.Dispatcher.CheckAccess() == true); Task.Factory.StartNew(LongWork, TaskCreationOptions.LongRunning); } void LongWork() { Debug.Assert(this.Dispatcher.CheckAccess() == false); Thread.Sleep(1000); } 所以Do()通常是从UI上下文中调用的。 ShortUIWork也是如此,由TaskScheduler定义。 但是,LongWork最终也会在UI线程中调用,当然,它会阻止UI。 如何确保UI线程中没有运行任务?

如何清空BlockingCollection

我有一个线程添加到BlockingCollection项目。 在另一个线程上我使用foreach (var item in myCollection.GetConsumingEnumerable()) 如果有问题,我想打破我的foreach和我的方法并清除BlockingCollection中剩下的任何东西但是我找不到办法去做。 有任何想法吗?

清理TPL中的CallContext

根据我是使用基于异步/等待的代码还是基于TPL的代码,我在清理逻辑CallContext遇到两种不同的行为。 如果我使用以下async / await代码,我可以完全按照我的预期设置和清除逻辑CallContext : class Program { static async Task DoSomething() { CallContext.LogicalSetData(“hello”, “world”); await Task.Run(() => Debug.WriteLine(new { Place = “Task.Run”, Id = Thread.CurrentThread.ManagedThreadId, Msg = CallContext.LogicalGetData(“hello”) })) .ContinueWith((t) => CallContext.FreeNamedDataSlot(“hello”) ); return; } static void Main(string[] args) { DoSomething().Wait(); Debug.WriteLine(new { Place = “Main”, Id = Thread.CurrentThread.ManagedThreadId, Msg = CallContext.LogicalGetData(“hello”) }); } […]

库中的Task.Yield()需要ConfigureWait(false)

建议您随时使用ConfigureAwait(false) ,尤其是在库中,因为它可以帮助避免死锁并提高性能。 我编写了一个大量使用async的库(访问数据库的Web服务)。 该库的用户遇到了僵局,经过多次痛苦的调试和修补后,我将其追踪到单独使用await Task.Yield() 。 我等待的其他地方,我使用.ConfigureAwait(false) ,但是在Task.Yield()上不支持。 对于需要相当于Task.Yield().ConfigureAwait(false)情况,建议使用什么解决方案Task.Yield().ConfigureAwait(false) ? 我已经了解了如何删除SwitchTo方法 。 我可以看出为什么这可能是危险的,但为什么没有相当于Task.Yield().ConfigureAwait(false) ? 编辑: 为了提供我的问题的进一步背景,这里是一些代码。 我正在实现一个开源库,用于访问支持异步的DynamoDB(作为AWS的服务的分布式数据库)。 许多操作返回IX-Async库提供的IAsyncEnumerable 。 该库不提供从以“块”提供行的数据源生成异步枚举的好方法,即每个异步请求返回许多项。 所以我有自己的通用类型。 该库支持预读选项,允许用户指定在调用MoveNext()实际需要之前应该请求多少数据。 基本上,这是如何工作的,我通过调用GetMore()并在这些之间传递状态来请求块。 我将这些任务放在一个chunks队列中并将它们出列并将它们转换为我放入单独队列的实际结果。 NextChunk()方法是这里的问题。 根据ReadAhead的值,我将在最后一个完成(All)之后保持获取下一个块,直到需要一个值但不可用(None)或仅获取超出当前值的下一个块使用(一些)。 因此,获取下一个块应该并行/不阻止获取下一个值。 枚举器代码是: private class ChunkedAsyncEnumerator : IAsyncEnumerator { private readonly ChunkedAsyncEnumerable enumerable; private readonly ConcurrentQueue<Task> chunks = new ConcurrentQueue<Task>(); private readonly Queue results = new Queue(); private CancellationTokenSource cts […]

为什么使用JpegBitmapDecoder的LongRunning任务(TPL)资源耗尽?

我们有一个托管的.Net / C#应用程序,可以创建TPL任务来对JPEG图像执行JPEG元数据编码。 每个任务都使用TaskCreationOptions.LongRunning选项构建,例如, Task task = new Task( () => TaskProc(), cancelToken, TaskCreationOptions.LongRunning ); TaskProc()利用JpegBitmapDecoder和JpegBitmapEncoder类添加JPEG元数据并将新图像保存到磁盘。 我们允许在任何时间最多激活2个此类任务,此过程应无限期地继续。 执行上述操作一段时间后,我们得到了足够的存储空间来处理此命令exception时尝试创建JpegBitmapDecoder类的实例: System.ComponentModel.Win32Exception(0x80004005):没有足够的存储空间可用于在MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d)处理此命令 在System.Windows.Threading的MS.Win32.HwndWrapper..ctor(Int32 classStyle,Int32 style,Int32 exStyle,Int3 2 x,Int32 y,Int32 width,Int32 height,String name,IntPtr parent,HwndWrapperHoo k [] hooks) System.Windows上的System.Windows.Threading.Dispatcher.get_CurrentDispatcher()处于System.Windows的System.Windows.Media.Imaging.BitmapDecoder..ctor(Stream bitmapStream,BitmapC reateOptions createOptions,BitmapCacheOption cacheOption,Guid expectedClsId)中的.Dispatcher..ctor() .Media.Imaging.JpegBitmapDecoder..ctor(流bitmapStream,Bit mapCreateOptions createOptions,BitmapCacheOption cacheOption) 仅当我们使用JpegBitmapDecoder添加元数据时才会发生错误。 换句话说,如果任务只是编码并将Bitmap图像保存到文件,则不会出现任何问题。 使用Process Explorer,Process Monitor或其他诊断工具时,没有显示任何明显的信息。 根本没有观察到线程,内存或句柄泄漏。 发生此类错误时,不会启动任何新应用程序,例如记事本,文字等。一旦我们的应用程序终止,一切都会恢复正常。 LongRunning的任务创建选项在MSDN中定义为指定任务将是长时间运行的粗粒度操作。 它向TaskScheduler提供了一个提示,即可以保证超额订阅。 这意味着选择运行任务的线程可能不是来自ThreadPool,即,它将为任务的目的而创建。 其他任务创建选项将导致为任务选择ThreadPool线程。 […]

可以/应该将任务包装在C#5.0中,等待TResult中的协变吗?

我非常喜欢使用C#5.0异步编程。 但是,有些地方更新旧代码以与TAP模型保持一致会给我带来问题。 这是其中之一 – 我不确定为什么Task在TResult中不协变,但在尝试更新协变接口以从同步模式转换为异步模式时,它会给我带来问题: 旧代码: public interface IInitializable // ** out generic modifier ** { /// /// Boolean to indicate if class is ready /// bool IsInitialized { get; } /// /// Calls for instance to be initialized using current parameters /// Driver initialization can be done in the default constructor if desired /// […]

立即返回任务

我有一份任务列表,我想等待。 我在等 await TaskEx.WhenAll(MyViewModel.GetListOfTasks().ToArray()); MyViewModel.GetListOfTasks()返回任务列表: var tasksList = new List(); foreach (var item in Items) { tasksList.Add(item.MyTask()); } 现在,我想返回虚假任务,这将立即完成。 但是,TaskEx.WhenAll会永远等待它: public Task MyTask() { return new Task(() => false); } 我怎样才能返回任务,这将立即完成?