2015-11-07 22 views
6

Jestem nowy w C# i wciąż uczę się koncepcji wątków. Napisałem program, który przedstawia się następującoThreading concept in C#

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Threading; 

namespace ConsoleApplication17 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     System.Threading.ThreadStart th1 = new System.Threading.ThreadStart(prnt); 
     Thread th = new Thread(th1); 
     th.Start(); 
     bool t = th.IsAlive; 
     for (int i = 0; i < 10; i++) 
     { 
      Console.WriteLine(i + "A"); 
     } 
    } 

    private static void prnt() 
    { 
     for (int i = 0; i < 10; i ++) 
     { 
      Console.WriteLine(i + "B"); 
     } 
    } 
    } 
} 

Oczekuję wyjście jak: -

1A 
2A 
1B 
3A 
2B... 

jak wierzę, że zarówno główny wątek i nowo utworzony wątek powinien być wykonujący jednocześnie.

Ale wyjście jest uporządkowane, najpierw wywoływana jest funkcja prnt, a następnie wykonywana jest metoda pętli .

+3

Twój kod wygląda dobrze; przypuszczalnie trwa to dłużej, zanim nić się zacznie, niż w przypadku głównego wątku. Dodaj 'Thread.Sleep (500);' do każdej pętli 'for'; pomoże to w zapewnieniu dłuższego czasu działania, aby można było zobaczyć, co się dzieje. – JohnLBevan

+1

Planowanie wątków nie jest przewidywalne i wiele programów zawiedzie (warunki wyścigu), ponieważ programista przyjął pewne idealne zachowanie dotyczące wątków, które nie istnieją, na przykład zakładając, że wątki zawsze działają równolegle i w doskonałej synchronizacji. Nie robią tego. Zastanów się, w jaki sposób twój program działa na procesorze z jednym gwintem i systemem operacyjnym z dużym (100 ms +) rozkładem czasu. – Dai

Odpowiedz

3

może 10 egzemplarzy nie wystarczy, aby zobaczyć dwa wątki w tym samym czasie. użyć dłuższej pętli lub umieścić Thread.Sleep (100) w iteracji cyklu. Rozpoczęcie wątku jest dość kosztowne. Prawdopodobnie dzieje się tak, że pętla główna zostanie wykonana przed uruchomieniem pętli wątku, ze względu na czas wymagany do uruchomienia wątku:

+0

Dzięki, działało z 100 iteracjami. – user2235487

2

Zgadzam się z poprzednimi odpowiedziami, aby dodać Thread.Sleep (kilka sekund * 1000)

polecam przeczytać ten artykuł o wątku https://msdn.microsoft.com/ru-ru/library/system.threading.thread(v=vs.110).aspx

static void Main(string[] args) 
    { 
     Thread th = new Thread(prnt); 
     th.Start(); 
     for (int i = 0; i < 10; i++) 
     { 
      //sleep one second 
      Thread.Sleep(1000); 
      Console.WriteLine(i + "A"); 
     } 
     //join the basic thread and 'th' thread 
     th.Join(); 
    } 
    private static void prnt() 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      //sleep one second 
      Thread.Sleep(1000); 
      Console.WriteLine(i + "B"); 
     } 
    } 
1

Updated: proces stosowany jest do izolowania aplikacji i nici uruchamiane w kontekście tego procesu.

W ten sposób system operacyjny może łatwiej zarządzać różnymi aplikacjami, zarządzać awariami i przełączaniem kontekstów (przedziały czasowe udostępniane każdej aplikacji przez CPU). Ideą jest po prostu uruchamianie wątków w zdefiniowanym przedziale czasowym, kiedy czas dozwolony na uruchomienie aplikacji się skończy, CPU przełączy się na inny wątek do wykonania.

Użyj klasy wątków dla małych asynchronicznych zadań w aplikacjach.

Zobacz, jak w poniższym przykładzie można utworzyć nowy wątek przy użyciu przestrzeni nazw System.Threading. Zauważ, jak wywoływana jest funkcja t.Join(), aby oczekiwać na zakończenie nowego wątku.

Zauważ, że Spleep (1) wymusi zmianę kontekstu i właśnie to robi różnicę. Spróbuj zmienić ją z powrotem na zero i zobacz wyniki.

using System; 
using System.Threading; 

namespace Chapter1 
{ 
    public static class Threads1 
    { 
     public static void ThreadMethod() 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       Console.WriteLine("ThreadProc: {0}", i); 
       Thread.Sleep(1); 
      } 
     } 
     public static void Main(string[] args) 
     { 
      Thread t = new Thread(new ThreadStart(ThreadMethod)); 
      t.Start(); 
      for (int i = 0; i < 4; i++) 
      { 
       Console.WriteLine("Main thread: Do some work."); 
       Thread.Sleep(1); 
      } 
      t.Join(); 

      Console.Read(); 
     } 
    } 
} 
// OUTPUT: 
//Main thread: Do some work. 
//ThreadProc: 0 
//ThreadProc: 1 
//Main thread: Do some work. 
//ThreadProc: 2 
//Main thread: Do some work. 
//ThreadProc: 3 
//Main thread: Do some work. 
//ThreadProc: 4 
//ThreadProc: 5 
//ThreadProc: 6 
//ThreadProc: 7 
//ThreadProc: 8 
//ThreadProc: 9 
+1

* "Wątek" służy do izolowania aplikacji i pozwala im działać we własnym procesie. * Nie, wątek nie jest procesem i nie izoluje "aplikacji". Wątek jest jednostką wykonawczą, umożliwiając wykonanie wielu prac * równolegle *. Wątek nadal znajduje się w logicznym kontekście procesu. –

+0

Zaktualizowano @YuvalItzchakov – Rober