Questions tagged «task-parallel-library»

自.NET 4开始,任务并行库是.NET Framework的一部分。它是一组API,使开发人员可以对异步应用程序进行编程。

6
CancellationToken的默认参数
我有一些要添加的异步代码CancellationToken。但是,在许多实现中都不需要这样做,因此我想有一个默认参数-也许CancellationToken.None。然而, Task<x> DoStuff(...., CancellationToken ct = null) 产量 不能将类型“”的值用作默认参数,因为没有对“ System.Threading.CancellationToken”类型的标准转换 和 Task<x> DoStuff(...., CancellationToken ct = CancellationToken.None) “ ct”的默认参数值必须是编译时常量 有什么办法可以为其设置默认值CancellationToken吗?

5
导致死锁的异步/等待示例
我遇到了一些使用c#的async/ await关键字进行异步编程的最佳实践(我是c#5.0的新手)。 给出的建议之一如下: 稳定性:了解您的同步上下文 ...某些同步上下文是不可重入的和单线程的。这意味着在给定时间只能在上下文中执行一个工作单元。Windows UI线程或ASP.NET请求上下文就是一个例子。在这些单线程同步上下文中,很容易使自己陷入僵局。如果您从单线程上下文中生成任务,然后在上下文中等待该任务,则您的等待代码可能会阻止后台任务。 public ActionResult ActionAsync() { // DEADLOCK: this blocks on the async task var data = GetDataAsync().Result; return View(data); } private async Task<string> GetDataAsync() { // a very simple async method var result = await MyWebService.GetDataAsync(); return result.ToString(); } 如果我自己剖析,则主线程会生成一个新线程MyWebService.GetDataAsync();,但是由于主线程在此等待,因此它将在中等待结果GetDataAsync().Result。同时,说数据准备好了。为什么主线程不继续其继续逻辑并从中返回字符串结果GetDataAsync()? 有人可以解释一下为什么上面的示例中出现死锁吗?我完全不知道问题是什么...

3
实施永无止境的任务的正确方法。(计时器与任务)
因此,只要应用程序正在运行或要求取消,我的应用程序就需要几乎连续地执行操作(每次运行之间有10秒左右的暂停)。它需要做的工作可能要花费30秒。 最好使用System.Timers.Timer并使用AutoReset确保在上一个“刻度”完成之前它不执行操作。 还是我应该在LongRunning模式下使用带有取消令牌的常规Task,并在其中执行常规的无限while循环,以调用之间用10秒的Thread.Sleep进行操作来执行操作?至于异步/等待模型,我不确定这里是否合适,因为我没有任何返回值。 CancellationTokenSource wtoken; Task task; void StopWork() { wtoken.Cancel(); try { task.Wait(); } catch(AggregateException) { } } void StartWork() { wtoken = new CancellationTokenSource(); task = Task.Factory.StartNew(() => { while (true) { wtoken.Token.ThrowIfCancellationRequested(); DoWork(); Thread.Sleep(10000); } }, wtoken, TaskCreationOptions.LongRunning); } void DoWork() { // Some work that takes …

3
需要了解SemaphoreSlim的用法
这是我的代码,但我不知道SemaphoreSlim在做什么。 async Task WorkerMainAsync() { SemaphoreSlim ss = new SemaphoreSlim(10); List<Task> trackedTasks = new List<Task>(); while (DoMore()) { await ss.WaitAsync(); trackedTasks.Add(Task.Run(() => { DoPollingThenWorkAsync(); ss.Release(); })); } await Task.WhenAll(trackedTasks); } void DoPollingThenWorkAsync() { var msg = Poll(); if (msg != null) { Thread.Sleep(2000); // process the long running CPU-bound job …

7
是否有基于任务的System.Threading.Timer替代品?
我是.Net 4.0的Task的新手,却找不到我认为是基于Task的计时器的替代品或实现,例如周期性Task。有这样的事吗? 更新 我提出了我认为是我需要的解决方案,该解决方案是将“计时器”功能包装在带有子任务的Task内,并全部利用CancellationToken并返回Task以便能够参与进一步的Task步骤。 public static Task StartPeriodicTask(Action action, int intervalInMilliseconds, int delayInMilliseconds, CancellationToken cancelToken) { Action wrapperAction = () => { if (cancelToken.IsCancellationRequested) { return; } action(); }; Action mainAction = () => { TaskCreationOptions attachedToParent = TaskCreationOptions.AttachedToParent; if (cancelToken.IsCancellationRequested) { return; } if (delayInMilliseconds > 0) Thread.Sleep(delayInMilliseconds); while …

7
是否建议prevTask.Wait()与ContinueWith一起使用(来自Tasks库)?
因此,最近有人告诉我,我如何将.ContinueWith用于任务不是正确的使用方式。我还没有在互联网上找到证据,所以我会问你们,看看答案是什么。这是我如何使用.ContinueWith的示例: public Task DoSomething() { return Task.Factory.StartNew(() => { Console.WriteLine("Step 1"); }) .ContinueWith((prevTask) => { Console.WriteLine("Step 2"); }) .ContinueWith((prevTask) => { Console.WriteLine("Step 3"); }); } 现在,我知道这是一个简单的示例,它将非常快速地运行,但是只要假设每个任务都进行更长的操作即可。因此,我被告知的是,在.ContinueWith中,您需要说prevTask.Wait();。否则,您可以在上一个任务完成之前进行工作。那有可能吗?我以为我的第二个和第三个任务只会在他们之前的任务完成后才运行。 有人告诉我如何编写代码: public Task DoSomething() { return Task.Factory.StartNew(() => { Console.WriteLine("Step 1"); }) .ContinueWith((prevTask) => { prevTask.Wait(); Console.WriteLine("Step 2"); }) .ContinueWith((prevTask) => { prevTask.Wait(); Console.WriteLine("Step …

7
Task.Run是否有参数?
我正在从事一个多任务网络项目,并且是的新手Threading.Tasks。我实现了一个简单的方法Task.Factory.StartNew(),不知道该如何处理Task.Run()? 这是基本代码: Task.Factory.StartNew(new Action<object>( (x) => { // Do something with 'x' }), rawData); 我System.Threading.Tasks.Task在对象浏览器中进行了调查,但找不到Action<T>相似的参数。只有Action这需要void参数,没有类型。 只有两件事是相似的:static Task Run(Action action)并且static Task Run(Func<Task> function)不能同时发布参数。 是的,我知道我可以创建一个简单的扩展方法,但我的主要问题是,我们可以把它写在一行用Task.Run()?

4
是否有类似异步BlockingCollection <T>的东西?
我想await基于BlockingCollection&lt;T&gt;.Take()异步的结果,所以我不阻塞线程。寻找这样的事情: var item = await blockingCollection.TakeAsync(); 我知道我可以这样做: var item = await Task.Run(() =&gt; blockingCollection.Take()); 但这有点使整个想法付诸东流,因为(的ThreadPool)另一个线程被阻塞了。 还有其他选择吗?

2
任务并行库替换BackgroundWorker?
任务并行库中是否有任何东西被认为是对BackgroundWorker类的替代或改进? 我有一个带有向导式UI的WinForms应用程序,它执行一些长期运行的任务。我希望能够拥有一个带有标准进度条的响应式UI,并能够取消该操作。我之前使用BackgroundWorker做到了这一点,但是我想知道是否可以使用某些TPL模式来代替?

6
如何防止任务上的同步继续?
我有一些库(套接字网络)代码,Task基于提供了一个基于API的未决请求响应TaskCompletionSource&lt;T&gt;。但是,TPL中有一个烦人之处在于,似乎不可能阻止同步继续。我会希望能够做的是两种: 告诉TaskCompletionSource&lt;T&gt;不允许呼叫者附加TaskContinuationOptions.ExecuteSynchronously,或者 设置结果(SetResult/ TrySetResult)的方式指定TaskContinuationOptions.ExecuteSynchronously应忽略的结果,而是使用池 具体来说,我的问题是传入的数据正在由专用的读取器处理,并且如果呼叫者可以附加TaskContinuationOptions.ExecuteSynchronously它们,则它们可能会使读取器停止运行(这不仅会影响读取器)。以前,我是通过一些黑客来解决此问题的,该黑客可以检测是否存在任何继续,如果将其继续,则将完成推送到上ThreadPool,但是如果调用者饱和了他们的工作队列,这将产生重大影响,因为不会处理完成及时地。如果他们正在使用Task.Wait()(或类似方法),则它们实际上将使自己陷入僵局。同样,这就是为什么阅读器使用专用线程而不使用工人的原因。 所以; 在尝试拖累TPL团队之前:我是否缺少选择? 关键点: 我不希望外部呼叫者能够劫持我的线程 我不能将ThreadPool用作实现,因为它在池饱和时需要工作 下面的示例产生输出(顺序可能会随时间而变化): Continuation on: Main thread Press [return] Continuation on: Thread pool 问题在于,一个随机调用者设法在“主线程”上获得了延续。在实际代码中,这会打断主要读者。坏事! 码: using System; using System.Threading; using System.Threading.Tasks; static class Program { static void Identify() { var thread = Thread.CurrentThread; string name = thread.IsThreadPoolThread ? "Thread pool" : thread.Name; …

2
在Task中捕获异常的最佳方法是什么?
使用System.Threading.Tasks.Task&lt;TResult&gt;,我必须管理可能引发的异常。我正在寻找做到这一点的最佳方法。到目前为止,我已经创建了一个基类,该基类在调用时管理所有未捕获的异常。.ContinueWith(...) 我想知道是否有更好的方法可以做到这一点。甚至是这样做的好方法。 public class BaseClass { protected void ExecuteIfTaskIsNotFaulted&lt;T&gt;(Task&lt;T&gt; e, Action action) { if (!e.IsFaulted) { action(); } else { Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =&gt; { /* I display a window explaining the error in the GUI * and I log the error. */ this.Handle.Error(e.Exception); })); } } } public class ChildClass …

6
我应该使用ThreadPools还是Task Parallel Library进行IO绑定操作
在我的一个有点像聚合器的项目中,我从网络上解析提要,播客等。 如果我使用顺序方法,那么考虑到大量的资源,要花所有的时间来处理所有这些资源(由于网络问题和类似的东西); foreach(feed in feeds) { read_from_web(feed) parse(feed) } 因此,我想实现并发性,无法决定是否应该基本上使用ThreadPools处理工作线程,还是仅依靠TPL对其进行排序。 ThreadPools肯定会通过辅助线程为我完成工作,并且我会得到期望的结果(在多核CPU环境中,其他内核也将被利用)。 但是我仍然想考虑TPL,因为它是推荐方法,但我对此有些担心。首先,我知道TPL使用ThreadPools,但增加了决策层。我最担心的是存在单核环境的情况。如果我没记错的话,TPL开头的工作线程数等于可用的CPU核心数。我确实担心TPL对于受IO约束的案例会产生与顺序方法相似的结果。 因此,对于IO绑定操作(以我为例,它是从Web上读取资源),最好是使用ThreadPools来控制事物,还是最好仅依赖TPL?TPL也可以用于IO绑定方案吗? 更新:我主要担心的是-在单核CPU环境中,TPL会像顺序方法一样工作还是会提供并发性?我已经在阅读《使用Microsoft .NET进行并行编程》,因此这本书却找不到确切的答案。 注意:这是我以前的问题的重新措辞[可以同时使用线程并发和并行性吗?]这句话是错误的。

2
将基于回调的异步方法转换为可等待任务的最佳方法
转换/包装使用回调的“经典”异步方法的最佳方法是什么,该方法返回一个(可等待的)任务? 例如,给定以下方法: public void GetStringFromUrl(string url, Action&lt;string&gt; onCompleted); 我知道将其包装到返回任务的方法中的唯一方法是: public Task&lt;string&gt; GetStringFromUrl(string url) { var t = new TaskCompletionSource&lt;string&gt;(); GetStringFromUrl(url, s =&gt; t.TrySetResult(s)); return t.Task; } 这是完成此任务的唯一方法吗? 并且有一种方法可以将对GetStringFromUrl(url,callback)的调用包装在任务本身中(即,调用本身将在任务内部运行而不是同步运行)

3
使用.NET 4.0任务模式使用HTTPClient .ReadAsAsync将JSON反序列化为数组或列表
我正在尝试反序列化http://api.usa.gov/jobs/search.json?query=nursing+jobs使用.NET 4.0任务模式返回的JSON 。它将返回此JSON(“加载JSON数据” @ http://jsonviewer.stack.hu/)。 [ { "id": "usajobs:353400300", "position_title": "Nurse", "organization_name": "Indian Health Service", "rate_interval_code": "PA", "minimum": 42492, "maximum": 61171, "start_date": "2013-10-01", "end_date": "2014-09-30", "locations": [ "Gallup, NM" ], "url": "https://www.usajobs.gov/GetJob/ViewDetails/353400300" }, { "id": "usajobs:359509200", "position_title": "Nurse", "organization_name": "Indian Health Service", "rate_interval_code": "PA", "minimum": 42913, "maximum": 61775, "start_date": "2014-01-16", …

4
是否可以保证Task.Factory.StartNew()使用调用线程以外的其他线程?
我正在从一个函数启动一个新任务,但我不希望它在同一线程上运行。我不在乎它在哪个线程上运行,只要它在另一个线程上即可(因此在此问题中无济于事)。 我是否保证下面的代码TestLock在Task t再次允许输入之前总是退出?如果不是,为防止重入,推荐的设计模式是什么? object TestLock = new object(); public void Test(bool stop = false) { Task t; lock (this.TestLock) { if (stop) return; t = Task.Factory.StartNew(() =&gt; { this.Test(stop: true); }); } t.Wait(); } 编辑:根据乔恩·斯凯特(Jon Skeet)和史蒂芬·图布(Stephen Toub)的以下回答,一种确定性地防止重入的简单方法是传递CancellationToken,如以下扩展方法所示: public static Task StartNewOnDifferentThread(this TaskFactory taskFactory, Action action) { return taskFactory.StartNew(action: action, cancellationToken: …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.