Tag: task parallel library

即使没有异步,CallContext.LogicalGetData也会被恢复。 为什么?

我注意到CallContext.LogicalSetData/LogicalGetData不按我预期的方式工作。 即使没有异步或任何类型的线程切换 , async方法中设置的值也会被恢复。 这是一个简单的例子: using System; using System.Runtime.Remoting.Messaging; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication { class Program { static async Task TestAsync() { CallContext.LogicalSetData(“valueX”, “dataX”); // commented out on purpose // await Task.FromResult(0); Console.WriteLine(CallContext.LogicalGetData(“valueX”)); return 42; } static void Main(string[] args) { using(ExecutionContext.SuppressFlow()) { CallContext.LogicalSetData(“valueX”, “dataXX”); Console.WriteLine(CallContext.LogicalGetData(“valueX”)); Console.WriteLine(TestAsync().Result); Console.WriteLine(CallContext.LogicalGetData(“valueX”)); } } } } 它产生这个输出: […]

Microsoft.Bcl.Async中是否存在ExceptionDispatchInfo的模拟?

Microsoft.Bcl.Async中是否存在ExceptionDispatchInfo的模拟? 我找不到类似的东西。 这个问题是由我的另一个问题引发的。 当exception的父task可用时,我可以使用task.GetAwaiter().GetResult()来重新抛出,如@StephenCleary所建议的那样。 当它不可用时,我有哪些选择?

我可以不等待异步任务而不使其异步无效吗?

使用异步任务方法时,需要在方法之前放置等待。 我需要以非UI阻塞方式执行代码,并且不想等待。 我唯一的想法是使用: private void TaskFactory() { CancellationTokenSource token_TaskFactory = new CancellationTokenSource(); ParallelOptions parOpts = new ParallelOptions(); parOpts.CancellationToken = token_TaskFactory.Token; parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount; TaskCreationOptions atp = new TaskCreationOptions(); atp = TaskCreationOptions.PreferFairness; Task TaskFactory = Task.Factory.StartNew(() => { if (!token_TaskFactory.IsCancellationRequested) { Thread.Sleep(5000); } else { } }, token_TaskFactory.Token, atp, TaskScheduler.Default); }

指定与对象并行的linq的任务超时

我有一个我希望并行处理的图片列表,但是超时。 我的旧代码通过分页项目和使用WaitHandles来做到这一点,但我想使用.Net 4中提供的新的Parallel Linq或Tasks库。 以下代码段正在运行,如何为其添加超时? (超时将用于执行的每个任务,而不是所有项目的超时处理) private PictureList FetchPictures(List wallResults) { wallResults .AsParallel() .WithDegreeOfParallelism(10) .ForAll(delegate(Picture p){

.NET中的并行抓取

我工作的公司运行着几百个非常动态的网站。 它决定建立一个搜索引擎,我的任务是编写刮刀。 一些站点在旧硬件上运行,不能承受太多惩罚,而其他站点可以处理大量的并发用户。 我需要能够说对站点A使用5个并行请求,对站点B使用2个,对站点C使用1个并行请求。 我知道我可以使用线程,互斥量,信号量等来实现这一目标,但它会非常复杂。 任何更高级别的框架,如TPL,await / async,TPL Dataflow是否足够强大,能够以更简单的方式完成此应用程序?

c#中的并行和工作分工?

(假设我有10个核心) 我写的时候: Parallel.For(0, 100, (i,state) => { Console.WriteLine(i); }); 问题: 为每个核心分配数量的公式是什么? (是100/10 ?) 在执行点,每个核心是否已经知道要处理哪些数字? 或者每次从[0..100]存储库中获取新数字时是否消耗(让我们暂时忽略块或范围)? i参数 – 它是指0..100索引还是每个线程中的相对索引及其“处理”数字?

跟踪多步骤任务的进度

我正在开发一个向客户端公开Web服务的简单服务器。 某些请求可能需要很长时间才能完成,并且在逻辑上分为多个步骤。 对于此类请求,需要在执行期间报告进度。 此外,可以在前一个请求完成之前启动新请求,并且要求两个请求同时执行(禁止某些特定于系统的限制)。 我想让服务器将TaskId返回给它的客户端,并让客户端使用TaskId跟踪请求的进度。 我认为这是一个很好的方法,我留下了如何管理任务的问题。 从未使用过TPL,我认为这是解决这个问题的好方法。 实际上,它允许我同时运行多个任务,而无需手动管理线程。 我甚至可以使用ContinueWith相对容易地创建多步骤任务。 但是,我无法想出一种跟踪任务进度的好方法。 我意识到,当我的请求包含一个“步骤”时,该步骤必须合作报告其状态。 在这一点上,我宁愿避免这种情况。 但是,当请求包含多个步骤时,我想知道当前正在执行哪个步骤并相应地报告进度。 我能想到的唯一方法是非常无聊: Task firstTask = new Task( () => { DoFirstStep(); return 3.14; } ); firstTask. ContinueWith( task => { UpdateProgress(“50%”); return task.Result; } ). ContinueWith( task => { DoSecondStep(task.Result); return “blah”; }. ContinueWith( task => { UpdateProgress(“100%”); return task.Result; } ). 即使这并不完美,因为我希望Task能够存储自己的进度,而不是让UpdateProgress更新一些已知的位置。 […]

在WebAPI中使用ContinueWith进行死锁

作为通过Web API公开一些现有代码的一部分,我们遇到了很多死锁。 我已经能够将这个问题提炼到这个非常简单的例子中,这个例子将永远挂起: public class MyController : ApiController { public Task Get() { var context = TaskScheduler.FromCurrentSynchronizationContext(); return Task.FromResult(1) .ContinueWith(_ => { }, context) .ContinueWith(_ => Ok(DateTime.Now.ToLongTimeString()), context); } } 对我来说,这段代码看起来很简单。 这可能看起来有点人为,但这只是因为我尝试尽可能地简化问题。 看起来像这样链接的两个ContinueWith会导致死锁 – 如果我注释掉第一个ContinueWith(实际上并没有做任何事情),它会正常工作。 我也可以通过不给出特定的调度程序来“修复”它(但这对我们来说不是一个可行的解决方案,因为我们的实际代码需要在正确/原始的线程上)。 在这里,我将两个ContinueWiths放在一起,但在我们的实际应用中,有很多逻辑正在发生,而ContinueWiths最终来自不同的方法。 我知道我可以使用async / await重写这个特定的例子,它会简化一些事情,似乎可以修复死锁。 但是,我们在过去几年中已经编写了大量遗留代码 – 其中大部分都是在异步/等待出现之前编写的,所以它大量使用了ContinueWith。 如果我们能够避免它,重写所有逻辑并不是我们现在想做的事情。 像这样的代码在我们遇到的所有其他场景(桌面应用程序,Silverlight应用程序,命令行应用程序等)中运行良好 – 它只是给我们这些问题的Web API。 有没有什么可以一般地解决这种僵局? 我正在寻找一种解决方案,希望不会重新编写所有的ContinueWith来使用async / await。 更新: 上面的代码是我控制器中的整个代码。 我试图用最少量的代码使这个可重复。 […]

共享范围等待

我有一个UserScope类,其function类似于TransactionScope ,即它将当前状态存储在本地线程中。 这当然不适用于await调用,在.NET 4.5.1中添加TransactionScope之前, TransactionScopeAsyncFlowOption也没有。 我可以使用什么替代线程本地,以便UserScope可以在单线程和multithreading场景中使用相同的? (如果我安装了4.5.1,我会反编译以查看TransactionScope是如何做到的。)这是我所拥有的简化版本: class User { readonly string name; public User(string name) { this.name = name; } public string Name { get { return this.name; } } } class UserScope : IDisposable { readonly User user; [ThreadStatic] static UserScope currentScope; public UserScope(User user) { this.user = user; currentScope = this; } […]

任务和任务.WaitAll具有超时exception处理

当使用Task.WaitAll等待任务并在WaitAll超时时指定超时时,我还必须单独观察任何未完成的任务(例如通过注册延续)? 这个post让我觉得答案是肯定的,但我还没有找到其他证实这一点的东西。 var random = new Random(); var tasks = Enumerable.Range(0, 10).Select((i) => Task.Factory.StartNew(() => { // Sleep 5-15 seconds Thread.Sleep(random.Next(5000, 15000)); throw new Exception(“Some exception.”); } )).ToArray(); try { // Wait for 10 seconds Task.WaitAll(tasks, 10000); } catch (AggregateException) { // Swallow } // Check to see how many tasks were unfinished tasks.Where(t => […]