2014-02-14 5 views
0

Я написал эту консольную программу:Как синхронизировать несколько потоков

static void Main(string[] args) 
{ 
    object sync = new object(); 
    Thread[] t = new Thread[10]; 
    int count = 0; 

    for (var i = 0; i < t.Length; i++) 
    { 
     t[i] = new Thread(() => 
     { 
      lock (sync) 
      { 
       int inc = count; 
       Console.WriteLine("Count: {0}", count); 
       count = inc + 1; 
      } 
     }); 
    } 

    foreach (var t1 in t) 
    { 
     t1.Start(); 
    } 

    foreach (var t1 in t) 
    { 
     t1.Join(); 
     Console.WriteLine("\nFinal Count= {0}", count); 
     Console.ReadKey(); 
    } 
} 

я получаю этот результат на выходе:

Count: 0 
Count: 1 
Count: 2 
Count: 3 
Count: 4 
Count: 5 
Count: 6 
Count: 7 

Final Count= 7 
Count: 8 
Count: 9 

и когда я запускаю приложение несколько раз я получаю больше, разные результаты , но я хочу, чтобы увидеть этот результат:

Count: 0 
Count: 1 
Count: 2 
Count: 3 
Count: 4 
Count: 5 
Count: 6 
Count: 7 
Count: 8 
Count: 9 

Final Count= 10 

почему это возвращение другого Ресул ts и как это исправить?

+0

'Count = вкл + 1;' имеет мало смысла. Опубликовать фактический код. –

+0

«Конечный счет» является достижимым, но если вы хотите, чтобы номера были в порядке, просто не используйте потоки. –

ответ

1

Ну, вместо этого:

foreach (var t1 in t) 
{ 
    t1.Join(); 
    Console.WriteLine("\nFinal Count= {0}", count); 
    Console.ReadKey(); 
} 

Вы должны написать:

foreach (var t1 in t) 
{ 
    t1.Join(); 

} 
Console.WriteLine("\nFinal Count= {0}", count); 
Console.ReadKey(); 

В противном случае вы будете иметь скачки и ваш код будет undeterministic.

+0

Действительно, как только будет записан исходный код, «Окончательный счет» отображается, как только обнаружен какой-либо один поток. На самом деле, я удивлен, что сообщение «Окончательный счет» появляется только один раз, так как я ожидаю увидеть его один раз за поток ... –

+0

Это было бы так, но у него есть Console.ReadKey() внутри цикла , –

+0

Конечно - программа даже не подходит к завершению. \ * facepalm \ * –

2

Попробуйте вручную не создавать или прекращать такие потоки, это трудоемкая операция, и она не масштабируется хорошо.

Вместо этого используйте ThreadPool.

Или лучше: использовать задачи и синхронизировать их с помощью await Task.WhenAll(list of your tasks)

+0

Не так быстро. Это явно «демо», это зависит от того, что должно быть выполнено в фактических потоках позже. –

+0

@HenkHolterman Я вижу, что вы имеете в виду (и это действительно так), но я по-прежнему рекомендую задачи вместо потоков. Если OP не предоставляет информацию о том, почему потоки будут лучше задач (длительные операции ... и т. Д.), Задачи будут обеспечивать более простые способы синхронизации их выполнения. – ken2k

Смежные вопросы