Tag: task

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

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

Async MVC.NET操作方法阻止任何其他HTTP请求

(我为改变问题而道歉) 以下代码片段来自MVC.NET控制器(.NET:v4.5; AspNet.MVC:v5.2.3)。 调用LongOperation后,它: 产生一个过程 等待完成 监视一些LOG文件 使用SignalR从LOG文件通知浏览器进度 (为简单起见,我省略了代码) 所有这一切都有效,只有在LongOperation运行时,控制器才会处理其他 HTTP请求。 在LongOperation完成后处理它们并且action方法将结果返回给AJAX调用。 我搞砸了什么? 先感谢您。 更新(对于@angelsix评论):这是一个简化的设置: 我已根据建议删除了async / await 根据建议添加断点 已validation它们如上所述被击中 基本上:相同的结果,请参阅console.log-ed文本和时间戳欢迎来自社区的任何帮助。 先感谢您! GUI和日志 Controller中的操作方法 [AjaxOnly] public ActionResult _RunLongOperation(string hubId) { try { for (int i = 0; i < 10; i++) { Thread.Sleep(1000); ProgressNotifierHub.Notify(hubId, string.Format("Notification from _RunLongOperation {0}", i)); } return new HttpStatusCodeResult(HttpStatusCode.OK, "_RunLongOperation : […]

C#TPL如何知道所有任务都完成了?

我有Loop生成任务。 码: Task task = null; foreach (Entity a in AAAA) { // create the task task = new Task(() => { myMethod(a); }, Token, TaskCreationOptions.None); task.Start(); } 正如你在每次迭代中看到的那样,任务对象有了新的初始化(.. new Task(()=> ..)我怎么知道所有的任务都完成了?

何时缓存任务?

我正在观看异步的禅:最佳性能的最佳实践和Stephen Toub开始谈论任务缓存,而不是缓存任务作业的结果,你自己缓存任务。 据我所知,为每项工作开始一项新任务是昂贵的,应尽量减少。 在28:00左右,他展示了这种方法: private static ConcurrentDictionary s_urlToContents; public static async Task GetContentsAsync(string url) { string contents; if(!s_urlToContents.TryGetValue(url, out contents)) { var response = new HttpClient().GetAsync(url); contents = response.EnsureSuccessStatusCode().Content.ReadAsString(); s_urlToContents.TryAdd(url, contents); } return contents; } 首先看起来像是一个很好的思考方法,你缓存结果,我没有考虑缓存获取内容的工作。 而且他展示了这种方法: private static ConcurrentDictionary<string, Task> s_urlToContents; public static Task GetContentsAsync(string url) { Task contents; if(!s_urlToContents.TryGetValue(url, out contents)) { contents […]

如何通过手动输入流将命令提供给cmd.exe进程?

问题听起来有点密集。 这是一个稍长的版本: 我需要让主循环等待用户输入,并且还要运行一个进程并等待用户输入要发送到的流的输入。 全文:我正在构建一个Cmd模拟器,起初一切看起来都很好:用户输入一个命令,它会回显到输出区域,处理完毕,StdOut和StdErrOut被捕获并添加到输出TextBox中。 唯一的问题是,当为每个命令创建并单独启动cmd进程时,没有保留任何状态。 既不是变量也不是代码页,也不是工作目录等。 所以我决定发明一点hack:输入一个开括号或右括号开始和停止收集命令而不是执行它们。 在右括号之后,在processBatch方法中使用命令列表(’batch’)将它们全部提供给cmd进程,并将其重定向输入。 工作得很好。 唯一的问题是,显然,现在我已经获得状态但是立即失去了响应,因此在批处理运行之前不会弹出任何错误。 因此,我决定将好的部分结合起来,而且,当我意识到,为了保持两个循环工作并等待我必须使用线程,我知道我正在找麻烦。 多年来我没有做过…… 在布局中,我选择了main()循环等待用户输入,startCMDtask()在任务中运行startCMD()。 这里扫描输入流,直到有数据,然后cmd进程处理它们。 但它不起作用。 List batch = new List(); public volatile string output = “+”; public volatile string outputErr = “-“; Process CMD; Task cmdTask; volatile Queue cmdQueue = new Queue(); volatile public bool CMDrunning = false; 这个工作得很好 private void processBatch() { Process p […]

为什么我的任务没有取消?

我正在运行一个定期curl到URL列表的流程,以测试这些网站的性能。 我的主程序基本上是一个do … sleep … while循环,每N秒调用一个函数runTest(),用键盘中断将其终止。 简述了基础知识,我的代码如下: public void runTest() { if(isRunning) { return; //Plus some logging that one or more of the tests hasn’t completed } try { isRunning = true; Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL); CancellationTokenSource cts = new CancellationTokenSource(httpTimeoutValueMs * 2); foreach (var url in urls) taskList.Add(doAsyncCurls(url, cts)) List listOfResults = Task.WhenAll(taskList.Select(x => x)).Result.ToList(); taskList.Clear(); } […]

为什么这个并行代码比它的类似非并行版本慢?

我有以下代码(从LINQPad复制)。 显然,看起来我不理解TPL如何工作或代码是垃圾,为什么并行版本运行速度比非并行版本慢? for (int i = 0; i < 100; i++) { ParallelOptions ops = new ParallelOptions(); ops.MaxDegreeOfParallelism = Environment.ProcessorCount; var watch = Stopwatch.StartNew(); Parallel.ForEach(Enumerable.Range(1, 10000000), ops, x => { int y = x + 1; }); watch.Stop(); Console.WriteLine(“Parallel: {0}”, watch.Elapsed.TotalSeconds); watch = Stopwatch.StartNew(); foreach (var x in Enumerable.Range(1, 10000000)) { int y = x […]

ThrowIfCancellationRequested似乎没有抛出任何exception

我有以下代码: CancellationTokenSource cts = new CancellationTokenSource(); ParallelOptions po = new ParallelOptions(); po.CancellationToken = cts.Token; Task.Factory.StartNew(() => { if (Console.ReadKey().KeyChar == ‘c’) cts.Cancel(); Console.WriteLine(“press any key to exit”); }); Parallel.ForEach(list, po, (algo) => { algo.Compute(); // this compute lasts 1 minute Console.WriteLine(“this job is finished”); po.CancellationToken.ThrowIfCancellationRequested(); }); 该list包含很少的元素。 当我按’c’时,所有的Compute方法都已经启动了。 当我按’c’时,不会抛出任何exception。 每个Compute方法都会继续执行,直到正常结束。 当我按’c’时,我想停止/杀死所有剩余的Compute方法。

Azure Web角色上的WaitHandleCannotBeOpenedException以Task.Wait()开头

返回后,以下(Web)角色入口点会导致抛出以下exception。 public class WebRole : RoleEntryPoint { public override bool OnStart() { Task.Run(() => { // Anything can be here, but the lamdbda can be empty too… }).Wait(); return true; } } 例外: mscorlib.dll中出现’System.Threading.WaitHandleCannotBeOpenedException’类型的第一次机会exception 附加信息:不存在给定名称的句柄。 很明显,这是从框架中抛出的。 这个例外似乎是无害的,我没有遇到任何问题。 我还好奇,为什么会这样呢? 有没有办法在角色启动方法中运行异步代码而不会导致此类exception? 编辑: 这是exception的调用堆栈: > mscorlib.dll!System.Threading.EventWaitHandle.OpenExisting(string name, System.Security.AccessControl.EventWaitHandleRights rights) Unknown Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRoleInternal() Unknown Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.StartRole() Unknown Microsoft.WindowsAzure.ServiceRuntime.dll!Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.StartRole.AnonymousMethod__2() Unknown mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, […]

用于处理c#中文件的multithreading任务

我一直在阅读很多关于线程的内容,但无法弄清楚如何找到我的问题的解决方案。 首先让我介绍一下这个问题。 我有需要处理的文件。 主机名和文件路径位于两个arrays中。 现在我想设置几个线程来处理文件。 要创建的线程数基于三个因素: A)最大线程数不能超过所有方案中唯一主机名的数量。 B) 必须按顺序处理具有相同主机名的文件。 IE我们无法同时处理host1 _file1和host1 _file2。 (数据完整性将受到威胁,这超出了我的控制范围。 C)用户可以限制可用于处理的线程数。 线程数仍受上述条件A的限制。 这纯粹是因为如果我们有大量的主机让我们说50 ..我们可能不希望同时处理50个线程。 在上面的示例中,最多可以创建6个线程。 最佳处理程序如下所示。 public class file_prep_obj { public string[] file_paths; public string[] hostname; public Dictionary my_dictionary; public void get_files() { hostname = new string[]{ “host1”, “host1”, “host1”, “host2”, “host2”, “host3”, “host4″,”host4″,”host5″,”host6” }; file_paths=new string[]{“C:\\host1_file1″,”C:\\host1_file2″,”C:\\host1_file3″,”C:\\host2_file1″,”C:\\host2_file2″,”C:\\host2_file2”, “C:\\host3_file1″,”C:\\host4_file1″,”C:\\host4_file2″,”C:\\host5_file1″,”C:\\host6_file1”}; //The dictionary provides a […]