Каковы различные способы реализации многопоточности в .net - PullRequest
1 голос
/ 07 апреля 2010

Я боролся с многопоточностью в течение нескольких дней.

Я не понимаю, каковы различные способы multithreading. Я прочитал немного о backgroundWorker, немного о создании объекта потока. Вчера я видел в delegate примере реализации многопоточности, вызвав BeginInvoke.

Я не понимаю, являются ли эти различные способы multithreading или одинаковыми для одного и того же фонового класса. Пожалуйста, помогите мне разъяснить это.

Ответы [ 3 ]

2 голосов
/ 07 апреля 2010

Мне это нравится объяснения очень.Может быть, они тоже вам помогут.
И еще есть эта статья тоже Джона Скита.

1 голос
/ 07 апреля 2010

любой поток без GUI является фоновым рабочим. В точечной сети распространенным способом использования потоков является создание объекта потока и присвоение ему основного метода потока, поэтому эта функция будет выполняться в фоновом режиме. Во-первых, я думаю, что вы должны прочитать следующие книги, чтобы получить более глубокие знания по этому вопросу

  • .NET Многопоточность
  • C # Руководство по потокам

Кроме того, в приложении с графическим интерфейсом, таком как WPF или приложение win form, единственным потоком, который может изменять элементы GUI, является основной поток (поток GUI), поэтому вы должны использовать begininvoke, используя этот поток, и поместить туда обратный вызов для изменения графический интерфейс, в противном случае вы получите недопустимое исключение операции.

другим способом использования потока будет использование пула потоков .net, как эти

   ThreadPool.QueueUserWorkItem(new WaitCallback(delegateMethod), data);

 private void delegateMethod(object data){
   //some stuff
 }
0 голосов
/ 08 апреля 2010

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

Во-вторых, класс BackgroundWorker - хорошее начало. Вам нужно будет создать столько экземпляров, сколько вам потребуется для запуска потоков. Для каждого из них вам придется кодировать метод DoWork () . Этот метод вызывается при запуске его операции путем вызова метода BackgroundWorker.RunWorkerAsync () . Код, который вы хотите поместить в событие DoWork (), - это код, который должен асинхронно выполняться в фоновом режиме, пока основной поток вашего приложения занят чем-то другим. Два других события: ProgressChanged () и RunWorkerCompleted () используются для ReportProgress () или для определения того, что делать, когда поток выполнит свою работу, независимо от того, к какому концу это относится (исключение, правильное завершение и т. д.), я использую BackgroundWorker большую часть времени, так как, с моей скромной точки зрения, он наиболее прост в использовании.

В-третьих, вы можете использовать класс System.Threading.Thread . Это немного сложнее, чем просто определить событие DoWork () и заставить его произойти, вызвав другой метод. Вам нужно будет познакомиться с делегатами . Короче говоря, делегаты - это типы методов или функций, которые используются для выполнения некоторой работы в фоновом режиме. Что касается этих делегатов, у вас может быть несколько методов одного и того же типа делегата, как я только что сказал, делегаты являются типами методов. У вас может быть несколько ссылок на делегата . Вы можете увидеть это также как сигнатуру метода. Затем, когда приходит время его использовать, вы должны ссылаться на метод для нужного делегата. Используя класс System.Threading.Thread, вы хотите обратить внимание на делегат ThreadStart .

delegate void DoWork(object sender);

private void btnProcessWork_Click(object sender, EventArgs e) {
    DoWork doWork = SimpleDoWorkMethod;
    // Then start using the delegate.
    Thread t = new Thread(new ThreadStart(doWork));
    t.Start(); // Launch the thread in background...
    // Do something else while the thread is working !!!
}

private void SimpleDoWorkMethod(object s) {
    // Do some work here...
}

В-четвертых, представьте делегатов как событие, поскольку события основаны на делегатах. На самом деле, вы предоставляете метод, который будет использоваться для обработки события, например, Button_Click (). Чтобы программно связать ваше событие btnProcess.Click с методом btnProcess_Click (), вам нужно написать:

btnProcess.Click += new EventHandler(btnProcess_Click);

То, что вы делаете здесь, это делает событие btnProcess.Click ссылкой на ваш метод btnProcess_Click (). Обратите внимание на делегат EventHandler с делегатом ThreadStart. Они служат для той же цели, но для двух разных реальностей (реакция на события в графическом интерфейсе и многопоточность).

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

Надеюсь, это немного поможет! =)

...