中止线程或仅让计算机清理它
本文关键字:计算机 线程 | 更新日期: 2023-09-27 17:56:40
我有以下代码,如果线程在 2 秒内未完成,我想中止它。您可以从第一个代码中看到,我在 while 循环中创建了一个新的 myThread evertyime,并且不会中止它。好吧,我不希望它像这样,但是如果我将myThread带到循环之外并像第二个代码一样使用abort()函数。中止时会出现错误。
while (true)
{
try
{
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//reset up socket
myThread = new System.Threading.Thread(new System.Threading.ThreadStart(socket_connect));
myThread.Start();
if (!myThread.Join(2000))
{
throw new SocketException(SocketError.AccessDenied);
}
}
catch (Exception ex)
{
m_socket.Close();
}
}
}
private static void socket_connect()
{
m_socket.Connect(remoteEndPoint);//Connect to remote device
}
我一开始尝试以下代码,但它给出了线程中止异常。
myThread = new System.Threading.Thread(new System.Threading.ThreadStart(socket_connect));
while (true)
{ try
{
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//reset up socket
myThread.Start();
if (!myThread.Join(2000))
{
myThread.Abort();
throw new SocketException(SocketError.AccessDenied);
}
}
catch (Exception ex)
{
m_socket.Close();
}
}
}
private static void socket_connect()
{
m_socket.Connect(remoteEndPoint);//Connect to remote device
}
我知道 abort() 不是一个好主意,所以我转而让线程留下来让 C#(.Net?我不知道谁实际上这样做)处理垃圾收集。谁能说出这是否是一个好主意,因为该程序将在没有大量内存来容纳线程束的板上运行。有人可以告诉我垃圾收集是如何在 C# 中完成的吗?例如线程。
另一件需要提及的事情是我没有 Task 类或 socket.beginconnect() 方法,我想这是因为我正在构建一个将在小板上运行的程序,而不是 PC。该板是一个netduido plus,我正在netduino plus平台上构建我的项目。
我有以下代码,如果线程在 2 秒内未完成,我想中止线程。
阅读代码,看起来您实际上想尝试在两秒钟内将套接字连接到资源。如果超过两秒,您要继续前进。
我主要是在这个答案中重现代码,我相信这大约是你应该做的来实现你的目标,而不是启动一个线程并中止它:
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
// Connect using a timeout (2 seconds)
IAsyncResult result = socket.BeginConnect( sIP, iPort, null, null );
bool success = result.AsyncWaitHandle.WaitOne( 2000, true );
if ( !success )
{
// NOTE, MUST CLOSE THE SOCKET
socket.Close();
throw new ApplicationException("Failed to connect server.");
}
// Success
//...
[编辑:取消制表符/空格时大量复制粘贴失败]
哦,请使用Task
库,处理这些情况更容易:
(LINQPad-Friendly blob)
void Main()
{
var canceller = new CancellationTokenSource();
var task = Task.Factory.StartNew(() => DoStuff(canceller.Token), canceller.Token);
if(!task.Wait(2000, canceller.Token))
{
canceller.Cancel();
task.Wait(2);
}
sw.Elapsed.Dump();
}
private Stopwatch sw;
private void DoStuff(CancellationToken token)
{
try
{
sw = Stopwatch.StartNew();
while(!token.IsCancellationRequested)
{
}
}
// no catch - rethrown exceptions must be checked on Task
finally
{
sw.Stop();
}
}
或者,您可以使用一些"退出标志"条件 - 线程启动器和线程运行程序都可以看到/更改的布尔值,并在while
条件下使用它。