Tag: task parallel library

如何聚合来自异步生成器的数据并将其写入文件?

我正在学习C#中的异步/等待模式。 目前我正在尝试解决这样的问题: 有一个生产者(硬件设备)每秒生成1000个数据包。 我需要将此数据记录到文件中。 设备只有一个ReadAsync()方法一次报告一个数据包。 我需要缓冲数据包并按照它们生成的顺序将它们写入文件,每秒只执行一次。 如果写入过程没有在下一批数据包准备好写入时及时完成,则写操作应该失败。 到目前为止,我写了类似下面的内容。 它有效,但我不确定这是否是解决问题的最佳方法。 有任何意见或建议吗? 在消费者需要汇总从生产者处收到的数据时,采用这种生产者/消费者问题的最佳做法是什么? static async Task TestLogger(Device device, int seconds) { const int bufLength = 1000; bool firstIteration = true; Task writerTask = null; using (var writer = new StreamWriter(“test.log”))) { do { var buffer = new byte[bufLength][]; for (int i = 0; i { foreach (var […]

Parallel.ForEach()更改模拟上下文

今天我们将新创建的ASP.NET应用程序部署到服务器,很快我们意识到存在一个与安全相关的奇怪问题导致应用程序崩溃。 这是一个内部应用程序,我们使用Impersonation来管理用户访问资源的方式。 但是,当用户尝试访问他们完全控制的文件夹时,应用程序会抛出“拒绝访问”exception。 exception实际上是一个AggregateException并且被抛出一个方法,该方法使用Parallel.ForEach枚举列表并在正文内部,它尝试访问该文件夹,但此时模拟上下文被更改并且工作线程运行作为应用程序池的标识,它无权访问该文件夹,因此exception。 为了确认这一点,我查看了Parallel.ForEach主体内部和内部的进程标识: string before = WindowsIdentity.GetCurrent().Name; Debug.WriteLine(“Before Loop: {0}”, before); Parallel.ForEach(myList, currentItem => { string inside = WindowsIdentity.GetCurrent().Name; Debug.WriteLine(“Inside Loop: {0} (Worker Thread {1})”, inside, Thread.CurrentThread.ManagedThreadId); }); 当我运行应用程序时,这是打印出来的: Before Loop: MyDomain\ImpersonatedUser Inside Loop: NT AUTHORITY\SYSTEM (Worker Thread 8) Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 6) Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 7) Inside Loop: […]

使用语句中的HttpClient导致任务被取消

我为我的api调用创建了一个FileResult : IHttpActionResult webapi返回类型。 FileResult从另一个URL下载文件,然后将流返回给客户端。 最初我的代码有一个如下所示的using语句: public async Task ExecuteAsync(CancellationToken cancellationToken) { try { HttpResponseMessage response; using (var httpClient = new HttpClient()) { response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new System.Net.Http.StreamContent( await httpClient.GetStreamAsync(this.filePath)) }; } return response; } catch (WebException exception) {…} } 但是,这会间歇性地导致TaskCanceledException 。 我知道如果在异步调用完成之前处理了HttpClient,Task的状态将变为取消。 但是因为我使用了await : Content = new System.Net.Http.StreamContent(await httpClient.GetStreamAsync(this.filePath)) ,它应该阻止HttpClient在任务完成过程中被处理掉。 […]

如何确定所有任务何时完成

这是启动多个任务的示例代码 Task.Factory.StartNew(() => { //foreach (KeyValuePair entry in dicList) Parallel.ForEach(dicList, entry => { //create and add the Progress in UI thread var ucProgress = (Progress)fpPanel.Invoke(createProgress, entry); //execute ucProgress.Process(); in non-UI thread in parallel. //the .Process(); must update UI by using *Invoke ucProgress.Process(); System.Threading.Thread.SpinWait(5000000); }); }); .ContinueWith(task => { //to handle exceptions use task.Exception member var […]

Await或Task.FromResult

我有一个服务可以说, public interface ISomeService { Task DoSomeExpensiveCheckAsync(string parameter); } 我有这个课程来消费这项服务。 它只需要做一些简单的空检查,然后返回服务响应。 public class SomeServiceConsumer { private readonly ISomeService _serviceClient; public SomeServiceConsumer(ISomeService serviceClient) { _serviceClient = serviceClient; } public async Task DoSomething1Async(string someParameter) { if (string.IsNullOrWhiteSpace(someParameter)) { return false; } return await _serviceClient.DoSomeExpensiveCheckAsync(someParameter); } //No async or await keywords public Task DoSomething2Async(string someParameter) { if (string.IsNullOrWhiteSpace(someParameter)) […]

代码契约和异步

将后置条件添加到返回Task异步方法的推荐方法是什么? 我已阅读以下建议: http://social.msdn.microsoft.com/Forums/hu-HU/async/thread/52fc521c-473e-4bb2-a666-6c97a4dd3a39 post建议将每个方法实现为同步,签约,然后将异步对应实现为简单的包装器。 不幸的是,我不认为这是一个可行的解决方案(也许是通过我自己的误解): 异步方法虽然被假定为同步方法的包装器,但是没有任何真正的代码契约,因此可以按照自己的意愿进行。 致力于异步的代码库不太可能为所有内容实现同步对应。 因此,实现包含await其他异步方法的新方法因此被强制为异步。 这些方法本质上是异步的,不能轻易转换为同步。 它们不仅仅是包装纸。 即使我们通过说我们可以使用.Result或.Wait()而不是await (这实际上会导致某些SyncContext死锁,并且无论如何都必须在异步方法中重写.Wait()来使后一点无效,我我仍然坚信第一点。 有没有其他想法,或者有什么我错过的代码合同和TPL?

使用TPL的Parallel.ForEach时跟踪进度

跟踪以下进度的最佳方式是什么? long total = Products.LongCount(); long current = 0; double Progress = 0.0; Parallel.ForEach(Products, product => { try { var price = GetPrice(SystemAccount, product); SavePrice(product,price); } finally { Interlocked.Decrement(ref this.current); }}); 我想将进度变量从0.0更新为1.0(当前/总)但我不想使用会对并行性产生负面影响的任何内容。

在当前线程上执行任务

是否可以在当前线程上强制执行任务同步执行? 也就是说,通过例如将一些参数传递给StartNew() ,可以生成此代码: Task.Factory.StartNew(() => ThisShouldBeExecutedSynchronously()); 表现得像这样: ThisShouldBeExecutedSynchronously(); 背景: 我有一个名为IThreads的界面: public interface IThreads { Task StartNew(Func func); } 我想有两个这样的实现,一个使用线程的普通: public class Threads : IThreads { public Task StartNew(Func func) { return Task.Factory.StartNew(func); } } 而且一个不使用线程(在某些测试场景中使用): public class NoThreading : IThreads { public Task StartNew(Func func) { // What do I write here? } } 我可以让NoThreading版本只调用func() […]

在c#中取消多个任务的正确方法是什么

我有一个按钮,可以产生4个任务。 相同的按钮更改为取消按钮,单击此按钮将取消所有4个任务。 我是否应该将相同的取消令牌传递给所有4个任务,并让它们在IsCancelRequested的相同令牌上进行轮询? 在createlinkedtokensource上阅读msdn doc后我很困惑。 这通常是怎么做的? 谢谢 更新:Task.WaitAll()等待所有任务完成执行 。 类似地,一旦共享取消令牌源设置为取消,如何知道何时取消所有任务 。

如何在TPL中为任务指定名称

我将在我的应用程序上运行许多任务。 由于某种原因,每一堆任务都在运行。 我想命名这些任务,所以当我观看Parallel Tasks窗口时,我可以轻松识别它们。 从另一个角度来看,考虑我在框架级别使用任务来填充列表。 使用我的框架的开发人员也在为她的工作使用任务。 如果她查看并行任务窗口,她会发现一些不知道的任务。 我想命名任务,以便她可以将框架任务与她的任务区分开来。 如果有这样的API会非常方便: var task = new Task(action, “Growth calculation task”) 或者可能: var task = Task.Factory.StartNew(action, “Populating the datagrid”) 甚至在使用Parallel.ForEach Parallel.ForEach(list, action, “Salary Calculation Task” 可以命名任务吗? 是否有可能为Parallel.ForEach一个命名结构(可能使用lambda),因此它使用该命名创建任务? 我错过了某个地方的API吗? 我还尝试使用inheritance的任务来覆盖它的ToString()。 但不幸的是,Parallel Tasks窗口不使用ToString()! class NamedTask : Task { private string TaskName { get; set; } public NamedTask(Action action, string taskName):base(action) { […]