0

このコードが機能しない理由を誰かが説明してくれませんか:

...
foreach (VisualChunk chunk in SortedChunks)
{
    System.Action a = () => MyFunction_Threaded(chunk);
    Console.Write("Synchronous : ");
    a.Invoke();
    System.Threading.Tasks.Task.Factory.StartNew(
                                        a,
                                        CancellationToken.None,
                                        TaskCreationOptions.None,
                                        TaskScheduler.Default)
} 
...

private void MyFunction_Threaded(VisualChunk chunk)
{
        Console.WriteLine(chunk.ChunkID);
}

console に次の出力が表示されます。

Synchronous : 0
Synchronous : 1
Synchronous : 2
Synchronous : 3
Synchronous : 4
Synchronous : 4294967291
Synchronous : 4294967292
Synchronous : 4294967293
Synchronous : 4294967294
Synchronous : 4294967295
Synchronous : 4294967296
Synchronous : 4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
4294967297
Synchronous : 4294967298
4294967298

実際、.net フレームワーク 4.5 がインストールされている場合 (win 8 または VS2012)、このコードは完全に機能します。4.0 のみをインストールすると、この問題が発生します。

4

1 に答える 1

1

はい、上記の@usrによるコメントで述べたように、コードの問題は、アセンブリ言語をビルドするときにコンパイラがやりたいことを多少誤解している「変更されたクロージャ」があることです。これは、c# 言語では非常に不適切な設計の選択です。これを回避するには、ループ内の変数のコピーをすぐに作成する必要があります。

foreach (VisualChunk chunk in SortedChunks)
{
  var chunkA = chunk;
  System.Action a = () => MyFunction_Threaded(chunkA);
  ...

しかし、これが何を意味するのか (つまり、このコードで何を達成しようとしているのか) を尋ねなければなりません。

于 2012-10-15T23:20:02.990 に答える