Ответ 1
Что-то вроде этого:
new Thread(delegate () {
updateProgress(count, totalRows);
}).Start();
В настоящее время я работаю над проектом на С#. У меня есть метод под названием updateProgress(), который имеет два параметра int (count и totalRows).
Если я вызвал метод, указав updateProgress (count, totalRows), это отлично работает, но я хочу запустить этот метод в новом потоке.
Как я могу это сделать, я смотрел онлайн, и все выглядит слишком сложно для того, что я хочу делать.
Спасибо за помощь с этим
Что-то вроде этого:
new Thread(delegate () {
updateProgress(count, totalRows);
}).Start();
Помните, что потоковая передача на самом деле довольно сложная тема, поэтому, если у вас возникли проблемы с пониманием асинхронных API-интерфейсов, доступных в .NET Framework, я сомневаюсь, что вы должны начать использовать потоки в первую очередь.
В любом случае у вас есть несколько вариантов:
Отбросьте нить самостоятельно (как указано cdhowie), что довольно обескуражено.
Используйте TPL (параллельную библиотеку задач), если вы работаете в .NET 4. Здесь - хорошее введение.
TaskFactory.StartNew(() => updateProgress(count, totalRows));
Используйте ThreadPool, если вы работаете в старой версии .NET.
ThreadPool.QueueUserWorkItem(s => updateProgress(count, totalRows));
Конечно, есть и другие способы, но это самые важные из них.
С наилучшими пожеланиями,
Оливер Ханаппи
Существуют разные способы запуска метода в другом потоке, например Thread
, BackgroundWorker
, ThreadPool
или Task
. Какой из них выбрать, зависит от разных вещей.
Из имени метода кажется, что метод должен показывать некоторый прогресс в графическом интерфейсе вашего приложения. Если это так, вам нужно запустить метод в потоке графического интерфейса. Если вы хотите вызвать его из другого потока, вы должны использовать Dispatcher.Invoke()
в WPF и Control.Invoke()
в WinForms.
Это почти год, и мой ответ не добавит ничего нового в то, что уже было сказано в других ответах.
Если кто-то использует .Net 4.0 или более поздней версии, лучшим вариантом будет использование задачи, и пусть фреймворк решает все, позвонив TaskFactory.StartNew(...)
. Для более старых версий все же лучше использовать пул потоков с помощью ThreadPool.QueueUserWorkItem(...)
.
Теперь, если по какой-то причине кто-то хочет использовать поток в основном (создавая новый поток), то этот
new Thread(delegate () {
updateProgress(count, totalRows);
}).Start();
может быть написано немного более чистым способом, используя выражение лямбда, например
new Thread(() => updateProgress(count, totalRows)).Start();
Здесь более сложный пример без анонимных делегатов. Посмотрите на результат в завершенной функции.
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker _bw;
static void Main()
{
_bw = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_bw.DoWork += bw_DoWork;
_bw.ProgressChanged += bw_ProgressChanged;
_bw.RunWorkerCompleted += bw_RunWorkerCompleted;
_bw.RunWorkerAsync ("Hello to worker");
Console.WriteLine ("Press Enter in the next 5 seconds to cancel");
Console.ReadLine();
if (_bw.IsBusy) _bw.CancelAsync();
Console.ReadLine();
}
static void bw_DoWork (object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i += 20)
{
if (_bw.CancellationPending) { e.Cancel = true; return; }
_bw.ReportProgress (i);
Thread.Sleep (1000); // Just for the demo... don't go sleeping
} // for real in pooled threads!
e.Result = 123; // This gets passed to RunWorkerCompleted
}
static void bw_RunWorkerCompleted (object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
Console.WriteLine ("You canceled!");
else if (e.Error != null)
Console.WriteLine ("Worker exception: " + e.Error.ToString());
else
Console.WriteLine ("Complete: " + e.Result); // from DoWork
}
static void bw_ProgressChanged (object sender,
ProgressChangedEventArgs e)
{
Console.WriteLine ("Reached " + e.ProgressPercentage + "%");
}
}
попробуйте выполнить
ThreadPool.QueueUserWorkItem((o) => { updateProgress(5, 6); });