在以前版本的Parallel Extensions中,您可以设置线程数:
enumerable.AsParallel(numberOfThreads)
Run Code Online (Sandbox Code Playgroud)
但是现在再也没有超载了.现在该怎么办?
我正在尝试.NET 4.0中的任务支持 - 特别是在继续支持的情况下.我困惑的是,我无法弄清楚如何继续TaskContinuationOptions.OnlyOnCanceled执行标志设置.如果我ThrowIfCancellationRequested在我的工作例程中执行,它似乎只是作为错误而不是取消操作传播出延续.例如,给定此代码:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace TaskExp1
{
class Program
{
static void Main()
{
var n = 10000;
DumpThreadId("main method");
var cts = new CancellationTokenSource();
var task = Task.Factory.StartNew<int>(_ => Sum(cts.Token, n),
cts.Token);
task.ContinueWith(t =>
{
DumpThreadId("ContinueWith Completed, ", newline:false);
Console.WriteLine("The result is " + t.Result);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith(t =>
{
DumpThreadId("ContinueWith Faulted, ", newline: false);
Console.WriteLine(t.Exception.InnerExceptions[0].Message);
}, TaskContinuationOptions.OnlyOnFaulted);
task.ContinueWith(_ =>
{
DumpThreadId("ContinueWith Cancelled, ");
}, TaskContinuationOptions.OnlyOnCanceled);
Console.WriteLine("Computing sum of …Run Code Online (Sandbox Code Playgroud) 我正在使用F#进行并行编程.使用固定数量的元素,例如具有2个元素a1,a2和函数f,我可以执行以下操作:
let t1 = Task.Factory.StartNew(fun () -> f a1)
let t2 = Task.Factory.StartNew(fun () -> f a2)
Task.WaitAll(t1, t2)
t1.Result, t2.Result
Run Code Online (Sandbox Code Playgroud)
我想知道如何用一系列元素做同样的事情:
let ts = List.map (fun a -> Task.Factory.StartNew(fun () -> f a))
Task.WaitAll(ts)
List.map (fun (t: Task<_>) -> t.Result) ts
Run Code Online (Sandbox Code Playgroud)
Visual Studio发现Task.WaitAll无法接受Task <T>列表作为其参数.Task.WaitAll可以将Task []作为其参数,但它没有意义,因为我需要获取Result以进行下一次计算.
我有一个具有大量IO操作的应用程序,例如文件复制,压缩和移动文件系统周围的文件,复制到备份服务器.
我将此程序构建为单线程.它运行2分钟.
我使用Parallel扩展并使用Task构建了该程序的另一个版本,它几乎在2分钟内运行.
换句话说,由于IO很大,我没有看到使用Parallels带来的性能提升.
如果我将应用程序部署到刀片服务器,我会得到相同的结果吗?
刀片服务器是否比我的工作站更快/更多地处理IO?
将Parallels与IO绑定应用程序一起使用没有任何好处吗?
情况:我有一个List<IQueryable<MyDataStructure>>.我想并行地对它们中的每一个运行一个linq查询,然后加入结果.
问题:如何创建我可以作为参数传递的linq查询?
示例代码:
这是一些简化的代码.首先,我有以下集合IQueryable<string>:
public List<IQueryable<string>> GetQueries()
{
var set1 = (new List<string> { "hello", "hey" }).AsQueryable();
var set2 = (new List<string> { "cat", "dog", "house" }).AsQueryable();
var set3 = (new List<string> { "cat", "dog", "house" }).AsQueryable();
var set4 = (new List<string> { "hello", "hey" }).AsQueryable();
var sets = new List<IQueryable<string>> { set1, set2, set3, set4 };
return sets;
}
Run Code Online (Sandbox Code Playgroud)
我想找到所有以字母"h"开头的单词.只需一个,IQueryable<string>这很容易:
query.Where(x => x.StartsWith("h")).ToList()
Run Code Online (Sandbox Code Playgroud)
但我希望对所有IQueryable<string>对象并行运行相同的查询,然后合并结果.这是一种方法:
var result = new ConcurrentBag<string>(); …Run Code Online (Sandbox Code Playgroud) 未来读者的更新:当.NET 4出现时,LazyInit<T>CTP将被重命名为Lazy<T>并将从一个结构更改为一个类,所以这几乎没有适用,除非为了说明为什么可变结构可能会有问题如果你不小心
我一直在使用Parallel Extensions June CTP中的LazyInit进行实验,我希望下面的代码可以打印出相同的Guid一千次,但它打印出一千种不同的Guid.很显然,我在这里遗漏了一些关于LazyInit应该如何工作的明显的东西,如果有人愿意指出它是什么,我会很感激.
using System;
using System.Diagnostics;
using System.Threading;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
for (int i=0; i < 1000; i++)
{
Console.WriteLine(TestClass.Instance.Id);
}
Console.Write("Press any key to continue:");
Console.ReadKey();
}
private class TestClass
{
private static readonly LazyInit<TestClass> _instance = new LazyInit<TestClass>(() => new TestClass(), LazyInitMode.EnsureSingleExecution);
public static TestClass Instance
{
get { return _instance.Value; }
}
private TestClass()
{
Debug.WriteLine("TestClass Constructor");
Id = Guid.NewGuid(); …Run Code Online (Sandbox Code Playgroud) Parallel.ForEach没有旋转新线程
大家好,我们有一个非常密集的IO操作,我们使用Microsoft的.NET Framework并行扩展中的Parallel.ForEach编写.我们需要删除大量文件,并且我们将要删除的文件表示为列表列表.每个嵌套列表中都有1000条消息,我们有50条这样的列表.这里的问题是,当我查看之后的日志时,我只看到在Parallel.ForEach块内执行一个线程.
这是代码的样子:
List<List<Message>> expiredMessagesLists = GetNestedListOfMessages();
foreach (List<Message> subList in expiredMessagesLists)
{
Parallel.ForEach(subList, msg =>
{
try
{
Logger.LogEvent(TraceEventType.Information, "Purging Message {0} on Thread {1}", msg.MessageID, msg.ExtensionID, Thread.CurrentThread.Name);
DeleteMessageFiles(msg);
}
catch (Exception ex)
{
Logger.LogException(TraceEventType.Error, ex);
}
});
}
Run Code Online (Sandbox Code Playgroud)
我写了一些示例代码,它具有更简单的数据结构,没有IO逻辑,我可以看到在Parallel.ForEach块中执行的几个不同的线程.我们在上面的代码中使用Parallel.ForEach做错了吗?它可能是绊倒它的列表列表,还是IO操作存在某种线程限制?
我在弄清楚如何Parallel.ForEach使用2D数组字符串调用时遇到了一些麻烦:
string[,] board = new string[,]{
{"A", "B", "C", "D", "E" },
{"F", "G", "H", "I", "J"},
{"K", "L", "M", "N", "O"},
{"0", "1", "2", "3", "4"}};
Parallel.ForEach(board, row =>
{
for (int i = 0; i < row.Length; ++i)
{
// find all valid sequences
}
});
Run Code Online (Sandbox Code Playgroud)
如果我没有明确指定类型,我会收到以下错误:
无法从用法中推断出方法'System.Threading.Tasks.Parallel.ForEach(System.Collections.Generic.IEnumerable,System.Action)'的类型参数.尝试显式指定类型参数.
明确指定类型参数的正确方法是什么?
我玩lambda,linq和parallel并且有一个问题到了.
lambda比linq查询更快吗?
O写一些测试代码(在GitHub中使用Fork),lambda方法似乎更快.这是真的还是我错过了什么?
我正在寻找一个TaskScheduler:
LimitedConcurrencyLevelTaskScheduler(使用线程池线程)或WorkStealingTaskScheduler执行此操作.目前我们TaskScheduler.Default用于通用池(受线程池增长算法等的支配)以及new OrderedTaskScheduler()每当我们想要订购任务时.我想保持这种行为,但将这两个要求限制在我自己的专用线程池中.
QueuedTaskScheduler似乎非常接近.我认为QueuedTaskScheduler.ActivateNewQueue()返回子TaskScheduler的方法会在父级的工作池上执行IN ORDER任务,但似乎并非如此.子TaskSchedulers似乎具有与父级相同的并行化级别.
我不一定希望子任务调度程序任务优先于父任务调度程序任务(尽管它将来可能是一个很好的功能).
我在这里看到了一个相关的问题:有限的并发级别任务调度程序(具有任务优先级)处理包装的任务,但我的要求不需要处理异步任务(我的所有排队任务从头到尾完全同步,没有延续).
c# multithreading task parallel-extensions task-parallel-library