Как стать автором
Обновить

Потоки в .NET. Часть 1

Время на прочтение 4 мин
Количество просмотров 14K
Этот топик дает начальные сведения об использовании потоков на платфоре .NET. Это мой первый пост на Хабре, поэтому не судите очень строго. Также хотелось бы услышать конструктивную критику о том, как можно улучшить материал.

Поток (thread) – это независимая последовательность инструкций в программе. Самый простой способ создания потоков– вызов делегата асинхронным образом.
static int TestThread(int data, int ms)
   {
     Console.WriteLine("TestThread started");
     Thread.Sleep(ms);
     Console.WriteLine("TestThread completed");
     return ++data;
   }

public delegate int TestThreadDelegate(int data, int ms);


* This source code was highlighted with Source Code Highlighter.

Есть несколько способов узнать завершил ли делегат свою работу.Это можно сделать с помощью метода BeginInvoke(), в котором входные параметры можно передать вместе с типом делегата. Этот метод возвращает тип IAsyncResult, у которого есть свойство IsCompleted. Вторым способом ожидания результата является использование дескриптора ожидания. Получить к нему доступ можно с помощью свойства AsyncWaitHandle. Третьим способом является использование обратного асинхронного вызова:
static void Main()
   {

     TestThreadDelegate d1 = TestThread;

     d1.BeginInvoke(1, 3000, TestThreadCompleted, d1);
     for (int i = 0; i < 100; i++)
     {
      Console.Write(".");
      Thread.Sleep(50);
     }

    }

static void TestThreadCompleted(IAsyncResult ar)
   {
     if (ar == null) throw new ArgumentNullException("ar");
     TestThreadDelegate d1 = ar.AsyncState as TestThreadDelegate;
     Trace.Assert(d1 != null, "Invalid object type");

     int result = d1.EndInvoke(ar);
     Console.WriteLine("result: {0}", result);
   }


* This source code was highlighted with Source Code Highlighter.

Другим способом создания потоков является использование класса Thread. Он также позволяет управлять ими.
using System;
using System.Threading;

namespace Csharp.Threading.FirstThread
{
  class Program
  {
   static void Main(string[] args)
   {
     Thread t1 = new Thread(ThreadMain);
     t1.Start();
     Console.WriteLine("This is the main thread.");
   }
   static void ThreadMain()
   {
     Console.WriteLine("In thread.");
   }
  }
}


* This source code was highlighted with Source Code Highlighter.

Передавать данные потокам можно двумя способами: используя конструктор Thread с делегатом ParameterizedThreadStart, либо путем создания специального класса и определения метода потока, как метода экземпляра:
public class MyThread
  {
   private string data;

   public MyThread(string data)
   {
     this.data = data;
   }

   public void ThreadMain()
   {
     Console.WriteLine("Running in a thread, data: {0}", data);
   }
  }


* This source code was highlighted with Source Code Highlighter.

В Main:
  MyThread obj = new myThread(“text”);

  Thread tr = new Thread(obj.ThreadMain);

  tr.Start();

* This source code was highlighted with Source Code Highlighter.

Существует два типа потоков: приоритетный и фоновый. Процесс продолжает выполняться до тех пор, пока выполняется хотя бы один приоритетный поток. С помощью класса Thread по умолчанию создается именно он. Чтобы поток был фоновым нужно использовать свойство IsBackground.

Операционная система планирует порядок выполнения потоков. На этот процесс можно влиять путем назначения потоку соответствующего приоритета с помощью свойства Priority.

Иногда нужно заранее создать набор потоков, также увеличивать или уменьшать этот набор при возникновении необходимости. Для этого предусмотрен класс ThreadPool.
using System;
using System.Threading;

namespace Csharp.Threading.Pools
{

  class Program
  {
   static void Main()
   {

     for (int i = 0; i < 5; i++)
     {
      ThreadPool.QueueUserWorkItem(JobForAThread);

     }

     Thread.Sleep(5000);
   }

   static void JobForAThread(object state)
   {
     for (int i = 0; i < 3; i++)
     {
      Console.WriteLine("loop {0}, running inside pooled thread {1}", i,
        Thread.CurrentThread.ManagedThreadId);
      Thread.Sleep(10);     
     }

   }
  }
}


* This source code was highlighted with Source Code Highlighter.

Но у пулов потоков есть некоторые ограничения: они являются фоновыми, также менять приоритет или имя потока в пуле нельзя.

Для начала это все. В следующий раз мы поговорим о взаимоблокировке и синхронизации потоков.

UPD. Перенес в .NET. Спасибо за карму.
Теги:
Хабы:
+6
Комментарии 23
Комментарии Комментарии 23

Публикации

Истории

Работа

.NET разработчик
66 вакансий

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн