С# Вызов метода в новом потоке
Я ищу способ вызова метода в новом потоке (используя С#).
Например, я хотел бы вызвать SecondFoo()
в новом потоке. Тем не менее, я хотел бы, чтобы поток завершился, когда SecondFoo()
завершится.
Я видел несколько примеров потоков в C#
, но ни один из них не применим к этому конкретному сценарию, где мне нужен порожденный поток, чтобы завершить себя. Это возможно?
Как заставить принудительно созданную нить, запущенную Secondfoo()
, завершиться после завершения?
Кто-нибудь сталкивался с подобными примерами?
Ответы
Ответ 1
Если вы действительно начинаете новый поток, этот поток прекращается, когда метод заканчивается:
Thread thread = new Thread(SecondFoo);
thread.Start();
Теперь в новом потоке будет вызываться SecondFoo
, и поток завершится, когда он будет завершен.
Вы действительно имели в виду, что хотите, чтобы поток завершился, когда завершен метод в вызывающем потоке?
EDIT: Обратите внимание, что запуск потока - это довольно дорогостоящая операция. Вам определенно нужен новый поток, а не поток threadpool? Рассмотрите возможность использования ThreadPool.QueueUserWorkItem
или (желательно, если вы используете .NET 4) TaskFactory.StartNew
.
Ответ 2
Действительно ли это должен быть поток, или это тоже может быть задача?
если это так, самый простой способ:
Task.Factory.StartNew(() => SecondFoo())
Ответ 3
В .Net Threads управляется пулом потоков, поэтому вы можете просто запустить его и забыть об этом! Рассмотрим этот код.
new Thread(new ThreadStart(SecondFoo)).Start();
Ответ 4
Если у вас есть особая ситуация, для которой требуется поток нить-пула, просто используйте поток пула потоков, например:
Action secondFooAsync = new Action(SecondFoo);
secondFooAsync.BeginInvoke(new AsyncCallback(result =>
{
(result.AsyncState as Action).EndInvoke(result);
}), secondFooAsync);
Gaurantees, которые EndInvoke вызывается, чтобы позаботиться о том, чтобы очистить вас.
Ответ 5
Асинхронная версия:
private async Task DoAsync()
{
await Task.Run(async () =>
{
//Do something awaitable here
});
}
Ответ 6
Насколько я понимаю, вы нуждаетесь в среднем конце как Thread.Abort()
правильно? В этом случае вы можете просто выйти из Foo(). Или вы можете использовать Process, чтобы поймать поток.
Thread myThread = new Thread(DoWork);
myThread.Abort();
myThread.Start();
Пример процесса:
using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Threading;
using Microsoft.VisualBasic;
class PrintProcessClass
{
private Process myProcess = new Process();
private int elapsedTime;
private bool eventHandled;
// Print a file with any known extension.
public void PrintDoc(string fileName)
{
elapsedTime = 0;
eventHandled = false;
try
{
// Start a process to print a file and raise an event when done.
myProcess.StartInfo.FileName = fileName;
myProcess.StartInfo.Verb = "Print";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(myProcess_Exited);
myProcess.Start();
}
catch (Exception ex)
{
Console.WriteLine("An error occurred trying to print \"{0}\":" + "\n" + ex.Message, fileName);
return;
}
// Wait for Exited event, but not more than 30 seconds.
const int SLEEP_AMOUNT = 100;
while (!eventHandled)
{
elapsedTime += SLEEP_AMOUNT;
if (elapsedTime > 30000)
{
break;
}
Thread.Sleep(SLEEP_AMOUNT);
}
}
// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
eventHandled = true;
Console.WriteLine("Exit time: {0}\r\n" +
"Exit code: {1}\r\nElapsed time: {2}", myProcess.ExitTime, myProcess.ExitCode, elapsedTime);
}
public static void Main(string[] args)
{
// Verify that an argument has been entered.
if (args.Length <= 0)
{
Console.WriteLine("Enter a file name.");
return;
}
// Create the process and print the document.
PrintProcessClass myPrintProcess = new PrintProcessClass();
myPrintProcess.PrintDoc(args[0]);
}
}