我正在研究一个multithreading的C#Windows应用程序,这个应用程序会频繁调用本地dll。 这些阻止有时可能持续相当长时间的电话。
在某些情况下,我想从主线程中取消一些工作线程的阻塞调用。我使用的本地API提供了一个用于此目的的函数:
HRESULT CancelBlockingCall(DWORD ThreadID)
虽然CancelBlockingCall()的文档不是很清楚,但我相信我需要传递阻塞在调用上的OS级线程的ThreadID。 根据我从CancelBlockingCall()得到的返回码,我意识到Thread.ManagedThreadID不是我所需要的。 我在msdn上find了以下内容(请参阅注释) :
操作系统ThreadId与托pipe线程没有固定关系,因为非托pipe主机可以控制托pipe线程和非托pipe线程之间的关系。 具体而言,复杂的主机可以使用CLR Hosting API来针对相同的操作系统线程调度多个托pipe线程,或者在不同的操作系统线程之间移动托pipe线程。
在C#.Net中,如何检测对话框是否显示?
.NET WinForms应用程序的MVC / MVP框架
无法加载可执行文件
我应该在Windows消息框中使用警告图标还是问号图标?
与.NET集成的Ruby on Rails的状态是什么?
这是否意味着我没有办法正确调用一个托pipe线程的CancelBlockingCall()? 是否无法确定托pipe线程当前正在执行的操作系统级线程的线程ID?
WIC / WPF:System.GPS.Longitude和System.GPS.Latitude始终返回NULL(通过BitmapMetadata)
将WPF应用程序分发给传统用户群:它有多无缝?
如何从WindowslockingWindows(如“Windows + L”)?
应用程序忙,但没有响应:如何检查它在做什么?
如果我对Windows服务进行了更改,是否必须运行installutil.exe?
这是否意味着我没有办法正确调用一个托管线程的CancelBlockingCall()? 是否无法确定托管线程当前正在执行的操作系统级线程的线程ID?
正如Aidan所说,您可以使用GetCurrentThreadID API来获取操作系统线程ID。
要通过托管线程跟踪它,可以将您的API调用包装在存储OS线程标识的类中,以便稍后停止:
public class APITask { private uint _osThreadId; public void Run() { _osThreadId = GetCurrentThreadID(); API.RunBlockingMethod(); } public void Cancel() { API.CancelBlockingCall(_osThreadId); } }
正如其他人提到的,你可以在调用阻塞本地函数之前尝试p /调用GetCurrentThreadId ,并在某个地方注册该id,但是这是一个时间炸弹 – 有一天,您的托管线程将被抢占并重新安排到不同的操作系统级别两个p / invoke调用之间的线程。 我可以建议的唯一可靠的方法是编写一个小型的非托管代理dll,它将首先调用GetCurrentThreadId (将它写入一个out IntPtr ,它将被托管代码看到),然后是本地阻塞函数。 回调到托管代码,而不是out IntPtr也可能工作; 当堆栈中存在非托管框架时,CLR几乎不能重新调度线程。
编辑:显然你不是第一个有这样的问题的人:在System.Threading.Thread有两个方便的方法,它们允许我们化解我提到的时间Thread.BeginThreadAffinity()和p /调用GetCurrentThreadId() : Thread.BeginThreadAffinity()和Thread.EndThreadAffinity() 。 CLR主机不会将托管线程重新安排到这些调用之间的其他本地线程。 尽管如此,您的代码需要以较高的信任级别来运行这些方法。
你可以尝试P /调用GetCurrentThreadID API
如何使用Abortable ThreadPool ?
从文章;
相反,请考虑一个线程池实现,它将一个排序的cookie传递给排队的工作项目。 池还可以提供一个取消方法,取得这些cookie中的一个,并取消相关的工作项目,将其从队列中移除或中止正在执行的工作项目。 为这个任务实现一个自定义线程池可能不是最好的主意,但还有其他的选择
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。