通过非托管代码调用Win32 TerminateThread() [英] Calling Win32 TerminateThread() via unmanaged code

查看:104
本文介绍了通过非托管代码调用Win32 TerminateThread()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程C#控制台应用程序,它使用WMI

(System.Management命名空间)对多个服务器(600+)进行RPC调用

并返回ScheduledJobs。执行查询的代码部分

包含在我通过第二个线程执行的委托函数中。在1 / $
或600多台服务器中的2台查询挂起。我试过使用Thread.Join()

加上一个Thread.Abort(),但这并没有杀死线程。


基于其他帖子我已经读过这是一个常见的事情,杀死这个线程的唯一方法就是使用位于Kernel32.dll中的TerminateThread()。

我我真的不确定如何调用这个非托管代码。还有TerminateThread()

需要线程的句柄,我不知道如何在.NET中获得这个。

我做了一个最佳猜测在代码但它不起作用。请参阅下面的示例。

任何人都可以给我一个如何完成此操作的代码示例吗?这是我的第一个

多线程应用程序,我几乎是非托管代码的新手。


//这个类允许我传递一个服务器名称为函数

//并仍然将其称为代理。


公共类Parcer

{

public int ThreadID;

private string Server;

public DataSet ds;

public Parcer(string Server)

{

this.Server = Server;

}


public void ParceJobs()

{

ThreadID = AppDomain.GetCurrentThreadId();

IntelJobReader JobReader = new IntelJobReader(); // Instanciate

JobReader对象。这是我编写的一个类,它使WMI调用和

返回一个DataSet。

DataSet JobSchedules =(DataSet)(JobReader.GetSvrJobs(Server));

this.ds = JobSchedules;

}

}


//这是我最好的猜测非托管代码。它运行没有错误,但

不会终止线程。


公共类Win32

{

[DllImport(" Kernel32.dll",CharSet = CharSet.Auto)]

public static extern int TerminateThread(int hThread);

}
< br $>
//摘自我的Conseole App的主要代码:


Parcer SchJobs =新的Parcer(服务器);

线程JobTimeout = new Thread(new ThreadStart(SchJobs.ParceJobs));

JobTimeout.Start();

JobTimeout.Join(10000);

if(!JobTimeout.Join(10000))

{

JobTimeout.Abort(); //这不会终止线程

Win32.TerminateThread(AppDomain.GetCurrentThreadId());

Console.WriteLine(&#;线程超时不会发生变化到

DB");

}


谢谢,

布莱恩

I have a multi-threaded C# console application that uses WMI
(System.Management namespace) to make RPC calls to several servers (600+ )
and returns ScheduledJobs. The section of my code that performs the query
is contained in a delegate function that I execute via a second thread. On 1
or 2 of the 600+ servers the query hangs. I''ve tried to use Thread.Join()
coupled with a Thread.Abort() but this does not kill the thread.

Based on other post I''ve read this is a common occurrence and the only way
to kill this thread is to use TerminateThread() located in the Kernel32.dll.
I''m not really sure how to call this unmanaged code. Also TerminateThread()
requires the thread''s handle and I''m not sure how to obtain this in .NET.
I''ve made a "best guess" at the code but it doesn''t work. See sample below.
Can anyone give me a code sample of how this can be done? This is my first
multi-threaded application and I''m pretty much a newbie to unmanaged code.

// This class allows me to pass a server name to the function
// and still call it as a delegate.

public class Parcer
{
public int ThreadID;
private string Server;
public DataSet ds;
public Parcer(string Server)
{
this.Server = Server;
}

public void ParceJobs()
{
ThreadID = AppDomain.GetCurrentThreadId();
IntelJobReader JobReader = new IntelJobReader(); //Instanciate the
JobReader object. This is a class I wrote that make the WMI calls and
returns a DataSet.
DataSet JobSchedules = ( DataSet ) ( JobReader.GetSvrJobs(Server) );
this.ds = JobSchedules;
}
}

// This is my best guess at the unmanaged code. It runs without error but
does not terminate the thread.

public class Win32
{
[DllImport("Kernel32.dll", CharSet=CharSet.Auto)]
public static extern int TerminateThread(int hThread);
}

// Excerpt from my Conseole App''s Main code:

Parcer SchJobs = new Parcer(Server);
Thread JobTimeout = new Thread(new ThreadStart(SchJobs.ParceJobs));
JobTimeout.Start();
JobTimeout.Join(10000);
if (!JobTimeout.Join(10000))
{
JobTimeout.Abort(); // This will not terminate the thread
Win32.TerminateThread(AppDomain.GetCurrentThreadId ());
Console.WriteLine("The thread timed out no change will be made to the
DB");
}

Thanks,
Bryan

推荐答案

>在600多台服务器中的1个或2个中查询挂起。我试过使用

Thread.Join()
> On 1 or 2 of the 600+ servers the query hangs. I''ve tried to use
Thread.Join()
加上一个Thread.Abort(),但是这并没有杀死线程。


首先确保序列是Thread.Abort()然后是Thread.Join(),而不是

其他方式。

首先调用Thread.Join()会导致僵局,你可能已经体验到了b $ b。


至于TerminateThread,这个API函数有两个参数(第二个

一个也是int),但我不确定如何获得

线程的句柄。您可能需要使用GetCurrentThread()API来实现这一点。


-

Dmitriy Lapshin [C#/ .NET MVP]

X-Unity测试工作室
http:/ /x-unity.miik.com.ua/teststudio.aspx

将单元测试的强大功能带到VS .NET IDE


" ;布赖恩" < TE ****** @ verizon.net>在消息中写道

news:yM ***************** @nwrddc01.gnilink.net ...我有一个多线程C#控制台应用程序使用WMI
(System.Management命名空间)对多个服务器(600+)进行RPC调用
并返回ScheduledJobs。我执行查询的代码部分包含在我通过第二个线程执行的委托函数中。在600多台服务器上的
1或2中查询挂起。我曾尝试使用Thread.Join()
加上一个Thread.Abort(),但这并不会杀死该帖子。

基于其他帖子我已读过这个杀死此线程的唯一方法是使用位于
Kernel32.dll中的TerminateThread()。我不确定如何调用这个非托管代码。另外
TerminateThread()需要线程的句柄,我不知道如何在.NET中获得它。
我做了一个最好的猜测。在代码但它不起作用。请参阅下面的示例
。谁能给我一个如何做到的代码示例?这是我的
第一个多线程应用程序,我几乎是非托管代码的新手。

//这个类允许我将服务器名称传递给函数
//并仍然将其称为委托。

公共类Parcer
{public int ThreadID;
私有字符串服务器;
公共DataSet ds ;
公共Parcer(字符串服务器)
{
this.Server = Server;
}
公共无效ParceJobs()
{
ThreadID = AppDomain.GetCurrentThreadId();
IntelJobReader JobReader = new IntelJobReader(); // Instanciate
JobReader对象。这是我编写的一个类,它使WMI调用并返回一个DataSet。
DataSet JobSchedules =(DataSet)(
JobReader.GetSvrJobs(Server)); this.ds = JobSchedules;
}
}
//这是我对非托管代码的最佳猜测。它运行没有错误,但
不会终止线程。

公共类Win32
{DllImport(" Kernel32.dll",CharSet = CharSet.Auto )]
public static extern int TerminateThread(int hThread);
}
//摘自我的Conseole App的主要代码:

Parcer SchJobs =新Parcer(服务器);
线程JobTimeout =新线程(新ThreadStart(SchJobs.ParceJobs));
JobTimeout.Start();
JobTimeout.Join(10000);
if(!JobTimeout.Join(10000))
{JobTimeout.Abort(); //这不会终止线程
Win32.TerminateThread(AppDomain.GetCurrentThreadId());
Console.WriteLine(线程超时,不会对
DB进行更改) );
}

谢谢,
布莱恩
coupled with a Thread.Abort() but this does not kill the thread.
Ensure the sequence was Thread.Abort() first and then Thread.Join(), not the
other way around.
Calling Thread.Join() first will result in a deadlock you are probably
experiencing.

As for the TerminateThread, this API function has two parameters (the second
one is also int), but I am not sure how one can obtain the handle of the
thread. You might need to resort to the GetCurrentThread() API to do that.

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Bryan" <te******@verizon.net> wrote in message
news:yM*****************@nwrddc01.gnilink.net... I have a multi-threaded C# console application that uses WMI
(System.Management namespace) to make RPC calls to several servers (600+ )
and returns ScheduledJobs. The section of my code that performs the query
is contained in a delegate function that I execute via a second thread. On 1 or 2 of the 600+ servers the query hangs. I''ve tried to use Thread.Join()
coupled with a Thread.Abort() but this does not kill the thread.

Based on other post I''ve read this is a common occurrence and the only way
to kill this thread is to use TerminateThread() located in the Kernel32.dll. I''m not really sure how to call this unmanaged code. Also TerminateThread() requires the thread''s handle and I''m not sure how to obtain this in .NET.
I''ve made a "best guess" at the code but it doesn''t work. See sample below. Can anyone give me a code sample of how this can be done? This is my first multi-threaded application and I''m pretty much a newbie to unmanaged code.

// This class allows me to pass a server name to the function
// and still call it as a delegate.

public class Parcer
{
public int ThreadID;
private string Server;
public DataSet ds;
public Parcer(string Server)
{
this.Server = Server;
}

public void ParceJobs()
{
ThreadID = AppDomain.GetCurrentThreadId();
IntelJobReader JobReader = new IntelJobReader(); //Instanciate the
JobReader object. This is a class I wrote that make the WMI calls and
returns a DataSet.
DataSet JobSchedules = ( DataSet ) ( JobReader.GetSvrJobs(Server) ); this.ds = JobSchedules;
}
}

// This is my best guess at the unmanaged code. It runs without error but
does not terminate the thread.

public class Win32
{
[DllImport("Kernel32.dll", CharSet=CharSet.Auto)]
public static extern int TerminateThread(int hThread);
}

// Excerpt from my Conseole App''s Main code:

Parcer SchJobs = new Parcer(Server);
Thread JobTimeout = new Thread(new ThreadStart(SchJobs.ParceJobs));
JobTimeout.Start();
JobTimeout.Join(10000);
if (!JobTimeout.Join(10000))
{
JobTimeout.Abort(); // This will not terminate the thread
Win32.TerminateThread(AppDomain.GetCurrentThreadId ());
Console.WriteLine("The thread timed out no change will be made to the
DB");
}

Thanks,
Bryan






你永远不应该调用ThreadTerminate,它会破坏进程,或者更糟糕的是,如果在操作系统堆上持有锁定时被调用,那么系统中的所有其他线程都是b $ b从同一堆分配/释放内存块将永远阻止
阻止。

从另一个线程(asynch。)调用Thread.Abort()也有问题:

1.当线程在非托管代码中被阻止时,Abort将暂停,直到从非托管代码返回

并且达到GC的安全点。

2.异步Thread.Abort'应该在执行finally

子句时延迟,这在v1.1中没有完成,可能导致资源泄漏s和

损坏的州。


我建议你修改你的管理/ WMI部分。代码,IMO

解决方案应该在那里找到,因为它是问题的根源

(阻塞线程)。

另一个指向检查您的代码是否在MTA线程上运行(请参阅主页上的
MTA / STAThread属性),太多人被此咬伤。


威利。

" Bryan" < TE ****** @ verizon.net>在消息中写道

新闻:yM ***************** @nwrddc01.gnilink.net ...
You should never call ThreadTerminate, it will corrupt the process, or
worse, if called while it holds a lock on the OS heap, all other threads in
the system trying to allocate/free memory blocks from the same heap will
block forever.
Calling Thread.Abort() from another thread (asynch.) is also problematic:
1. When the thread is blocked in unmanaged code, Abort will suspend until a
return from unmanaged code is done and a safe point for GC is reached.
2. Asynchronous Thread.Abort''s should be deferred when executing a finally
clause, this is not done in v1.1, possibly resulting in resource leaks and
corrupted state.

I would suggest you revise the portion of your "Management/WMI" code, IMO
the solution should be found in there as it''s the source of the problem
(blocking thread).
Another point to check is whether your code runs on a MTA thread (see
MTA/STAThread attribute on Main), too many people get bitten by this.

Willy.
"Bryan" <te******@verizon.net> wrote in message
news:yM*****************@nwrddc01.gnilink.net...
我有一个多线程C#控制台应用程序,它使用WMI
(System.Management命名空间)对多个服务器(600+)进行RPC调用,然后返回ScheduledJobs。我执行查询的代码部分包含在我通过第二个线程执行的委托函数中。在600多台服务器上的
1或2中查询挂起。我曾尝试使用Thread.Join()
加上一个Thread.Abort(),但这并不会杀死该帖子。

基于其他帖子我已读过这个杀死此线程的唯一方法是使用位于
Kernel32.dll中的TerminateThread()。我不确定如何调用这个非托管代码。另外
TerminateThread()需要线程的句柄,我不知道如何在.NET中获得它。
我做了一个最好的猜测。在代码但它不起作用。请参阅下面的示例
。谁能给我一个如何做到的代码示例?这是我的
第一个多线程应用程序,我几乎是非托管代码的新手。

//这个类允许我将服务器名称传递给函数
//并仍然将其称为委托。

公共类Parcer
{
public int ThreadID;
私有字符串服务器;
公共DataSet ds;
公共Parcer(字符串服务器)
{
this.Server = Server ;


public void ParceJobs()
{
ThreadID = AppDomain.GetCurrentThreadId();
IntelJobReader JobReader = new IntelJobReader(); // Instanciate
JobReader对象。这是我编写的一个类,它使WMI调用并返回一个DataSet。
DataSet JobSchedules =(DataSet)(
JobReader.GetSvrJobs(Server)); this.ds = JobSchedules;
}
}
//这是我对非托管代码的最佳猜测。它运行没有错误,但
不会终止线程。

公共类Win32
{DllImport(" Kernel32.dll",CharSet = CharSet.Auto )]
public static extern int TerminateThread(int hThread);
}
//摘自我的Conseole App的主要代码:

Parcer SchJobs =新Parcer(服务器);
线程JobTimeout =新线程(新ThreadStart(SchJobs.ParceJobs));
JobTimeout.Start();
JobTimeout.Join(10000);
if(!JobTimeout.Join(10000))
{JobTimeout.Abort(); //这不会终止线程
Win32.TerminateThread(AppDomain.GetCurrentThreadId());
Console.WriteLine(线程超时,不会对
DB进行更改) );
}

谢谢,
布莱恩
I have a multi-threaded C# console application that uses WMI
(System.Management namespace) to make RPC calls to several servers (600+ )
and returns ScheduledJobs. The section of my code that performs the query
is contained in a delegate function that I execute via a second thread. On 1 or 2 of the 600+ servers the query hangs. I''ve tried to use Thread.Join()
coupled with a Thread.Abort() but this does not kill the thread.

Based on other post I''ve read this is a common occurrence and the only way
to kill this thread is to use TerminateThread() located in the Kernel32.dll. I''m not really sure how to call this unmanaged code. Also TerminateThread() requires the thread''s handle and I''m not sure how to obtain this in .NET.
I''ve made a "best guess" at the code but it doesn''t work. See sample below. Can anyone give me a code sample of how this can be done? This is my first multi-threaded application and I''m pretty much a newbie to unmanaged code.
// This class allows me to pass a server name to the function
// and still call it as a delegate.

public class Parcer
{
public int ThreadID;
private string Server;
public DataSet ds;
public Parcer(string Server)
{
this.Server = Server;
}

public void ParceJobs()
{
ThreadID = AppDomain.GetCurrentThreadId();
IntelJobReader JobReader = new IntelJobReader(); //Instanciate the
JobReader object. This is a class I wrote that make the WMI calls and
returns a DataSet.
DataSet JobSchedules = ( DataSet ) ( JobReader.GetSvrJobs(Server) ); this.ds = JobSchedules;
}
}

// This is my best guess at the unmanaged code. It runs without error but
does not terminate the thread.

public class Win32
{
[DllImport("Kernel32.dll", CharSet=CharSet.Auto)]
public static extern int TerminateThread(int hThread);
}

// Excerpt from my Conseole App''s Main code:

Parcer SchJobs = new Parcer(Server);
Thread JobTimeout = new Thread(new ThreadStart(SchJobs.ParceJobs));
JobTimeout.Start();
JobTimeout.Join(10000);
if (!JobTimeout.Join(10000))
{
JobTimeout.Abort(); // This will not terminate the thread
Win32.TerminateThread(AppDomain.GetCurrentThreadId ());
Console.WriteLine("The thread timed out no change will be made to the
DB");
}

Thanks,
Bryan



Hello Willy,
Hello Willy,
另一个要检查的问题是你的代码是否在MTA线程上运行(参见Main上的MTA / STAThread属性),有太多人被这个问题所困扰。


你能详细说明一下吗?我知道什么是STA,什么是MTA,但

它是如何与中止工作线程相关的?


-

Dmitriy Lapshin [C#/ .NET MVP]

X-Unity测试工作室
http://x-unity.miik.com.ua/teststudio.aspx

将单元测试的强大功能带到VS .NET IDE


" Willy Denoyette [MVP]" <无线************* @ pandora.be>写在消息中

新闻:Ot ************** @ TK2MSFTNGP09.phx.gbl ...你永远不应该调用ThreadTerminate,它会破坏这个过程,或者
更糟糕的是,如果在操作系统堆上锁定时被调用,系统中试图从同一堆中分配/释放内存块的所有其他线程
将永久阻塞。
从另一个线程(asynch。)调用Thread.Abort()也有问题:
1.当线程在非托管代码中被阻塞时,Abort将暂停,直到
a从非托管代码返回并且安全达到GC的点。
2.执行finally
子句时应该延迟异步Thread.Abort',这在v1.1中没有完成,可能导致资源泄漏并且
腐败状态。

我建议你修改你的管理/ WMI部分。代码,IMO
解决方案应该在那里找到,因为它是问题的根源
(阻塞线程)。
要检查的另一点是你的代码是否在MTA线程上运行(参见主页上的MTA / STAThread属性),太多人被此咬伤了。

Willy。

" Bryan" < TE ****** @ verizon.net>在消息中写道
新闻:yM ***************** @nwrddc01.gnilink.net ...
Another point to check is whether your code runs on a MTA thread (see
MTA/STAThread attribute on Main), too many people get bitten by this.
Could you please elaborate on this? I know what is STA and what is MTA, but
how does it related to aborting a worker thread?

--
Dmitriy Lapshin [C# / .NET MVP]
X-Unity Test Studio
http://x-unity.miik.com.ua/teststudio.aspx
Bring the power of unit testing to VS .NET IDE

"Willy Denoyette [MVP]" <wi*************@pandora.be> wrote in message
news:Ot**************@TK2MSFTNGP09.phx.gbl... You should never call ThreadTerminate, it will corrupt the process, or
worse, if called while it holds a lock on the OS heap, all other threads in the system trying to allocate/free memory blocks from the same heap will
block forever.
Calling Thread.Abort() from another thread (asynch.) is also problematic:
1. When the thread is blocked in unmanaged code, Abort will suspend until a return from unmanaged code is done and a safe point for GC is reached.
2. Asynchronous Thread.Abort''s should be deferred when executing a finally
clause, this is not done in v1.1, possibly resulting in resource leaks and
corrupted state.

I would suggest you revise the portion of your "Management/WMI" code, IMO
the solution should be found in there as it''s the source of the problem
(blocking thread).
Another point to check is whether your code runs on a MTA thread (see
MTA/STAThread attribute on Main), too many people get bitten by this.

Willy.
"Bryan" <te******@verizon.net> wrote in message
news:yM*****************@nwrddc01.gnilink.net...
我有一个多线程C#控制台应用程序使用WMI
(System.Management命名空间)对多个服务器进行RPC调用
(600+)并返回ScheduledJobs。执行
查询的代码部分包含在我通过第二个线程执行的委托函数中。
I have a multi-threaded C# console application that uses WMI
(System.Management namespace) to make RPC calls to several servers (600+ ) and returns ScheduledJobs. The section of my code that performs the query is contained in a delegate function that I execute via a second thread. On
1
或查询挂起的600多台服务器中的2个。我曾尝试使用
or 2 of the 600+ servers the query hangs. I''ve tried to use


Thread.Join()加上一个Thread.Abort(),但这并没有杀死线程。

基于其他帖子我'我已经读过这是一个常见的事情而且杀掉这个线程的唯一
方法是使用位于

Thread.Join() coupled with a Thread.Abort() but this does not kill the thread.

Based on other post I''ve read this is a common occurrence and the only way to kill this thread is to use TerminateThread() located in the


Kernel32.dll中的TerminateThread()。


Kernel32.dll.

I 我真的不确定如何调用这个非托管代码。另外
I''m not really sure how to call this unmanaged code. Also


TerminateThread()


TerminateThread()

需要线程的句柄,我不知道如何在
..NET中获取它。我做了一个最好的猜测在代码但它不起作用。请参阅下面的示例
requires the thread''s handle and I''m not sure how to obtain this in ..NET. I''ve made a "best guess" at the code but it doesn''t work. See sample


任何人都可以给我一个如何完成此操作的代码示例吗?这是我的
Can anyone give me a code sample of how this can be done? This is my


第一个

多线程应用程序,我几乎是非托管
代码的新手。
multi-threaded application and I''m pretty much a newbie to unmanaged code.

//这个类允许我将服务器名称传递给函数
//并仍然将其称为委托。

公共类Parcer
{
public int ThreadID;
private string Server;
public DataSet ds;
public Parcer(string Server)
{
this.Server = Server;
}

public void ParceJobs()
{
ThreadID = AppDomain.GetCurrentThreadId();
IntelJobReader JobReader = new IntelJobReader(); // Instanciate

// This class allows me to pass a server name to the function
// and still call it as a delegate.

public class Parcer
{
public int ThreadID;
private string Server;
public DataSet ds;
public Parcer(string Server)
{
this.Server = Server;
}

public void ParceJobs()
{
ThreadID = AppDomain.GetCurrentThreadId();
IntelJobReader JobReader = new IntelJobReader(); //Instanciate



JobReader对象。这是我编写的一个类,它使WMI调用并返回一个DataSet。
DataSet JobSchedules =(DataSet)(


the JobReader object. This is a class I wrote that make the WMI calls and
returns a DataSet.
DataSet JobSchedules = ( DataSet ) (


JobReader.GetSvrJobs(Server));


JobReader.GetSvrJobs(Server) );

this.ds = JobSchedules;
}
}

//这是我对非托管代码的最佳猜测。它运行没有错误
但是没有终止线程。

公共类Win32
{DllImport(" Kernel32.dll",CharSet = CharSet.Auto )]
public static extern int TerminateThread(int hThread);
}
//摘自我的Conseole App的主要代码:

Parcer SchJobs =新Parcer(服务器);
线程JobTimeout =新线程(新ThreadStart(SchJobs.ParceJobs));
JobTimeout.Start();
JobTimeout.Join(10000);
if(!JobTimeout.Join(10000))
{JobTimeout.Abort(); //这不会终止线程
Win32.TerminateThread(AppDomain.GetCurrentThreadId());
Console.WriteLine(线程超时,不会对
更改数据库) );
}

谢谢,
布莱恩
this.ds = JobSchedules;
}
}

// This is my best guess at the unmanaged code. It runs without error but does not terminate the thread.

public class Win32
{
[DllImport("Kernel32.dll", CharSet=CharSet.Auto)]
public static extern int TerminateThread(int hThread);
}

// Excerpt from my Conseole App''s Main code:

Parcer SchJobs = new Parcer(Server);
Thread JobTimeout = new Thread(new ThreadStart(SchJobs.ParceJobs));
JobTimeout.Start();
JobTimeout.Join(10000);
if (!JobTimeout.Join(10000))
{
JobTimeout.Abort(); // This will not terminate the thread
Win32.TerminateThread(AppDomain.GetCurrentThreadId ());
Console.WriteLine("The thread timed out no change will be made to the DB");
}

Thanks,
Bryan







这篇关于通过非托管代码调用Win32 TerminateThread()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆