Tag: task parallel library

使用Reader Writer Lock创建线程安全列表

完全编辑早期版本,以下实现可以是线程安全列表实现。 我只需要知道它是否真的是线程安全的,我知道性能明智仍然存在问题。 目前版本正在使用ReaderWriterLockSlim,我有另一个使用Lock的实现,做同样的工作 使用System.Collections.Generic; 使用System.Threading; /// /// Thread safe version of the List using ReaderWriterLockSlim /// /// public class ThreadSafeListWithRWLock : IList { // Internal private list which would be accessed in a thread safe manner private List internalList; // ReaderWriterLockSlim object to take care of thread safe acess between multiple readers and writers private […]

Async / Await等同于.ContinueWith和CancellationToken以及TaskScheduler.FromCurrentSynchronizationContext()调度程序

这是这个问题的后续行动。 问题 :使用async / await而不是.ContinueWith()来表达以下内容的简洁方法是什么?: var task = Task.Run(() => LongRunningAndMightThrow()); m_cts = new CancellationTokenSource(); CancellationToken ct = m_cts.Token; var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); Task updateUITask = task.ContinueWith(t => UpdateUI(t), ct, TaskContinuationOptions.None, uiTaskScheduler); 我主要对UI SynchronizationContext的情况感兴趣(例如对于Winforms) 请注意,该行为具有以下所有期望的行为: 当CancellationToken被取消时, updateUITask最终会被取消(即LongRunningAndMightThrow工作可能仍会持续很长时间)。 在运行UpdateUI lambda之前, 在UI线程上检查ct CancellationToken是否取消(请参阅此答案 )。 在task完成或出现故障的某些情况下, updateUITask最终会被取消(因为在执行UpdateUI lambda之前在UI线程上检查了ct CancellationToken。 在UI线程上检查CancellationToken和UpdateUI lambda的运行之间没有中断。 也就是说,如果只在UI线程上取消了CancellationTokenSource ,那么在检查CancellationToken和运行UpdateUI lambda之间没有竞争条件 – 没有什么可以在这两个事件之间触发CancellationToken ,因为UI线程在这两个事件之间没有放弃。 讨论: […]

使用事务与任务并行库

我有N个进程来运行SQL Server 2008.如果任何进程失败,我需要回滚所有其他进程。 我正在考虑使用TPL创建父任务和N子任务。 所有这些都包含在transactionScope(IsolationLevel.ReadCommitted)中,但在我的下面的例子中, child2抛出一个错误(customers2不是一个有效的表),而child1没有回滚。 我在这里做错了吗? 还有其他方法来管理这种情况吗? 这是我的测试代码: 编辑我使用当前事务上的DependClone修改了如下代码。 我认为是有效的。 try { using (TransactionScope mainTransaction = TransactionUtils.CreateTransactionScope()) { var parentTransactionClone1 = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); var parentTransactionClone2 = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); var parentTask = Task.Factory.StartNew(() => { var childTask1 = Task.Factory.StartNew(() => { using (TransactionScope childScope1 = new TransactionScope(parentTransactionClone1)) { SqlConnection cnn = new SqlConnection(“Server=.\\sqlexpress;Database=northwind;Trusted_Connection=True;”); cnn.Open(); SqlCommand cmd = […]

为什么Task对象不可重用?

这个问题引出了另一个更普遍的(也可能是基本的)问题,为什么Task对象不可重用? 微软在没有解释的情况下写下这 任务只能启动并仅运行一次。 任何第二次安排任务的尝试都将导致exception。 这背后的推理是如此明显,以至于它不值得解释吗? 重复设置和启动具有Continuation的Task是否没有性能损失?

非阻塞和重复发生的生产者/消费者通知者实施

搜索了一段代码,它做了我想要的,我很满意。 读这个 , 这有很大帮助。 我有一个场景,我需要单个消费者在新数据可用时通知单个生产者,但也希望定期通知消费者,无论新数据是否可用。 如果通知消费者的时间超过了重复发生的时间,那就没有问题,但不应该频繁通知消费者。 当消费者已经通知并正在工作时,可能会发生“新数据”的多个通知。 (所以SemaphoreSlim不太适合)。 因此,比生产者通知速率慢的消费者不会排队后续通知,他们只是“重新发信号通知”相同的“数据可用”标志而没有影响。 我还希望消费者异步等待通知(不阻塞线程)。 我已经将下面的类包裹在一起,它包含了TaskCompletionSource并且还使用了一个内部Timer。 public class PeriodicalNotifier : IDisposable { // Need some dummy type since TaskCompletionSource has only the generic version internal struct VoidTypeStruct { } // Always reuse this allocation private static VoidTypeStruct dummyStruct; private TaskCompletionSource internalCompletionSource; private Timer reSendTimer; public PeriodicalNotifier(int autoNotifyIntervalMs) { internalCompletionSource = […]

可以使用任务并行库一起运行长时间运行的方法和“工作…”对话框,以允许长任务写入BindingList吗?

我有一个WPF(C#和.NET 4)应用程序,其中有一个长时间运行的任务阻止了UI,给人的印象是它已挂起。 我决定使用BackgroundWorker线程将这个长时间运行的任务放到一个单独的线程中,并在一个单独的弹出窗口中显示一个BusyIndicator (下面名为WorkingDialog)。 这很好用,直到长时间运行的任务写入BindingList(绑定到UI上的网格),我得到以下exception: 这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection 这是(业务层代码的一个非常精简的版本)… public class CustomMessage { public DateTime TimeStamp { get; private set; } public string Message { get; private set; } public CustomMessage(string message) { Message = message; TimeStamp = DateTime.Now; } } public class MyRandomBusinessClass { public BindingList LoggingList { get; private set; } public MyRandomBusinessClass() { LoggingList […]

使用.AsParallel()。ForAll或Parallel.ForEach性能问题并行化任务

我有一个网站列表和一个代理服务器列表。 我有这个动作 Action action = (string url) => { var proxy = ProxyHandler.GetProxy(); HtmlDocument html = null; while (html == null) { try { html = htmlDocumentLoader.LoadDocument(url, proxy.Address); // Various db manipulation code ProxyHandler.ReleaseProxy(proxy); } catch (Exception exc) { Console.WriteLine(“{0} proxies remain”, ProxyHandler.ListSize()); // Various db manipulation code proxy = ProxyHandler.GetProxy(); } } }; 我打电话给谁 […]

如何使用C#任务并行库和IProducerConsumerCollection实现通用回调?

我有一个组件向基于Web的API提交请求,但必须限制这些请求,以免违反API的数据限制。 这意味着所有请求必须通过队列来控制它们的提交速率,但它们可以(并且应该)同时执行以实现最大吞吐量。 每个请求必须在完成后的某个时刻将某些数据返回给调用代码。 我正在努力创建一个很好的模型来处理数据的返回。 使用BlockingCollection我不能只从Schedule方法返回Task ,因为入队和出队进程位于缓冲区的两端。 因此,我创建了一个RequestItem类型,其中包含Action<Task>forms的回调。 这个想法是,一旦一个项目被从队列中拉出,就可以用启动的任务调用回调,但是我已经丢失了那个点的generics类型参数,而且我还在使用reflection和各种恶作剧(如果它是甚至可能)。 例如: public class RequestScheduler { private readonly BlockingCollection _queue = new BlockingCollection(); public RequestScheduler() { this.Start(); } // This can’t return Task, so returns void. // Instead RequestItem is generic but this poses problems when adding to the queue public void Schedule(RequestItem request) { _queue.Add(request); } private […]

AZURE:在workerrole中异步运行Run()

我有一个异步任务。 async Task UploadFiles() { } 我想在azure workerrole的Run()方法中对UploadFiles()调用’await’。 但’await’仅适用于声明为异步的方法。 所以我可以像下面那样使Run()方法异步: public override void Run() { UploadFiles(); } 至 public async override void Run() { await UploadFiles(); }

为什么这个代码在通过TPL / Tasks执行时会失败?

我正在使用System.Net.Http来使用网络资源。 在单个线程上运行时,它可以完美运行。 当我通过TPL运行代码时,它会挂起并且永远不会完成,直到达到超时。 所发生的是所有线程最终都在sendTask.Result行上等待。 我不确定他们在等什么,但我认为它是HttpClient中的东西。 网络代码是: using (var request = new HttpRequestMessage(HttpMethod.Get, “http://google.com/”)) { using (var client = new HttpClient()) { var sendTask = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead); using (var response = sendTask.Result) { var streamTask = response.Content.ReadAsStreamAsync(); using (var stream = streamTask.Result) { // problem occurs in line above } } } } 我使用的TPL代码如下。 Do方法包含上面的代码。 […]