注私は自分が何を求めているかをよく知っており、通常はこのような関数を使用する必要はありませんが、私は階乗実験の大学院プロジェクトの研究要素として使用されています。実施。
PLINQ(TPLではない)を使用して実行したい次の関数があります。PLINQがTPL上で実行されることは知っていますが、実験のこの部分です。さらに、PLINQでそれを行う別の方法を知らない限り、再帰を伴うforループを使用するには、階乗メソッドをいくらか「ハック」する必要があると思います。
ParallelクラスはFor、ForEach、およびInvokeのみを提供するため、TPLが行うことなど、必要なものを提供しません。戻る必要があります。Invokeはそれを行いません。したがって、Forを使用してforループを実行する必要があります。再帰呼び出しごとに0,1から(はい、それはばかげているように見えることを私は知っています)。
私は次のようなことをしたいです:
public ulong RecursivePLINQ(ulong factor)
{
if (factor > 1)
{
Parallel.For<ulong>(0, 1, () => factor, (j, loop, factorial) =>
{
Thread.Sleep(1); /*Simulate Moderate Operation*/
return factorial * RecursivePLINQ(--factorial);
}, (i) => { });
}
return 1;
}
現在、機能しているように見えますが、最後の呼び出しで1が返され、再帰呼び出しの結果は1であり、再帰的に変更された値ではありません。何が悪いのかわからないようです。私はここに示されている代替のTPL実装(これも研究用)を持っていますが、これは機能しています。
public ulong RecursiveTPL(ulong factor)
{
if (factor > 1)
{
Task<ulong> task = new Task<ulong>((f) =>
{
Thread.Sleep(1); /*Simulate Moderate Operation*/
ulong val = (ulong)f;
return factor * RecursiveTPL(--val);
}, factor);
task.Start();
task.Wait();
return task.Result;
}
return 1;
}
***もう一度、私が求めていることを非難しないでください。それは非常に具体的な研究目的のためです* ****
編集スレッドローカル変数の使用を示すMSDNドキュメントの例を見たので、このようなことを試しましたが、頭が少し回転し始めています...キャストに注意を払わないでください。動作させる...
public ulong RecursivePLINQ(ulong factor)
{
long total = 0;
if (factor > 1)
{
Parallel.For<ulong>(0, 1, () => factor, (j, loop, factorial) =>
{
Thread.Sleep(1); /*Simulate Moderate Operation*/
return factorial * RecursivePLINQ(--factorial);
}, (i) => Interlocked.Add(ref total,(long)i)
);
}
return (ulong)total;
}