C# 在新线程中调用方法
Posted
技术标签:
【中文标题】C# 在新线程中调用方法【英文标题】:C# Call a method in a new thread 【发布时间】:2011-12-22 06:39:57 【问题描述】:我正在寻找一种在新线程上调用方法的方法(使用 C#)。
例如,我想在一个新线程上调用SecondFoo()
。但是,我希望在SecondFoo()
完成时终止线程。
我在C#
中看到了几个线程示例,但没有一个适用于我需要生成的线程自行终止的特定场景。这可能吗?
如何强制运行Secondfoo()
的衍生线程在完成后终止?
有人遇到过这样的例子吗?
【问题讨论】:
当 Secondfoo() 返回时,它正在运行的线程将终止。为什么你认为它没有? 有什么原因不能使用线程池吗? 【参考方案1】:如果你真的启动了一个新线程,该线程将在方法结束时终止:
Thread thread = new Thread(SecondFoo);
thread.Start();
现在SecondFoo
将在新线程中被调用,线程完成后将终止。
您是否实际上的意思是希望线程在调用线程中的方法完成时终止?
编辑:请注意,启动线程是一项相当昂贵的操作。您肯定需要一个全新的新 线程而不是使用线程池线程吗?考虑使用ThreadPool.QueueUserWorkItem
或(最好,如果您使用.NET 4)TaskFactory.StartNew
。
【讨论】:
就是这样 :-) 我不知道当没有更多语句要执行时线程终止。所以这就是我需要的确切答案。非常感谢!!!【参考方案2】:它真的必须是一个线程,还是也可以是一个任务?
如果是这样,最简单的方法是:
Task.Factory.StartNew(() => SecondFoo());
【讨论】:
或者只是Task.Run
@Omu 仍然必须确保 Tas.Run 满足性能需求
@Omu 是的,你是对的,任务更快。 Task.Run 的性能特别值得关注。见***.com/questions/18038776/…和blog.stephencleary.com/2013/11/…
StartNew is Dangerous,请改用Task.Run
。【参考方案3】:
一旦线程启动,就没有必要保留对 Thread 对象的引用。线程继续执行,直到线程过程结束。
new Thread(new ThreadStart(SecondFoo)).Start();
【讨论】:
这段代码实际上创建了一个新线程,而不是线程池线程 谢谢亚历克斯。重新阅读我的答案后,我也很惊讶!已更正。【参考方案4】:异步版本:
private async Task DoAsync()
await Task.Run(async () =>
//Do something awaitable here
);
【讨论】:
【参考方案5】:除非你有特殊情况需要非线程池线程,否则就使用这样的线程池线程:
Action secondFooAsync = new Action(SecondFoo);
secondFooAsync.BeginInvoke(new AsyncCallback(result =>
(result.AsyncState as Action).EndInvoke(result);
), secondFooAsync);
保证调用 EndInvoke 来为您进行清理。
【讨论】:
我之前使用 beginInvoke 在新线程中运行长处理报告。这是一篇关于 BeginInvoke 的 MSDN 文章:msdn.microsoft.com/en-us/library/2e08f6yc%28v=vs.71%29.aspx【参考方案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]);
【讨论】:
以上是关于C# 在新线程中调用方法的主要内容,如果未能解决你的问题,请参考以下文章