C# 线程池线程&;倾听事件

C# 线程池线程&;倾听事件,c#,C#,我有一个线程池线程,它已经订阅了一个事件,事件处理程序在另一个线程上被触发。我的问题是,线程池线程何时会返回到池中,或者只要事件订阅处于活动状态,线程池线程是否会一直存在 例如: public class RunTasks { private readonly MyTask _myTask; public RunTasks(MyTask myTask) { _myTask = myTask; }

我有一个线程池线程,它已经订阅了一个事件,事件处理程序在另一个线程上被触发。我的问题是,线程池线程何时会返回到池中,或者只要事件订阅处于活动状态,线程池线程是否会一直存在

例如:

public class RunTasks
    {
        private readonly MyTask _myTask;

        public RunTasks(MyTask myTask)
        {
            _myTask = myTask;
        }

        public void Execute()
         {
             ThreadPool.QueueUserWorkItem((ignore) => _myTask.Execute());
         }
    }

    public class MyTask
    {
        private readonly IThridPartyApi _dependency;

        public MyTask(IThridPartyApi dependency)
        {
            _dependency = dependency;
        }

        public void Execute()
        {
            _dependency.UpdateEvent -= Handler;
            _dependency.UpdateEvent += Handler;
        }

        private void Handler(object sender, EventArgs e)
        {
            //raised on another thread as it's coming from a thrid party library.
        }
    }

    public interface IThridPartyApi
    {
        event EventHandler<EventArgs> UpdateEvent;
    }
公共类运行任务
{
私有只读MyTask\u MyTask;
公共运行任务(MyTask MyTask)
{
_myTask=myTask;
}
public void Execute()
{
ThreadPool.QueueUserWorkItem((忽略)=>\u myTask.Execute());
}
}
公共类MyTask
{
private readonly IThridPartyApi_依赖项;
公共MyTask(IThridPartyApi依赖项)
{
_依赖=依赖;
}
public void Execute()
{
_dependency.UpdateEvent-=处理程序;
_dependency.UpdateEvent+=处理程序;
}
私有void处理程序(对象发送方、事件参数)
{
//在另一个线程上提出,因为它来自第三方图书馆。
}
}
公共接口IThridPartyApi
{
事件处理程序UpdateEvent;
}
在上面的示例中,让我们假设RunTasks.Execute方法被调用多次(范围为100),事件处理程序被触发50次,并被延迟50次-有多少活动线程将侦听事件订阅?我的应用程序中有这样的场景,所以我正在努力确保我没有从这个实现中创建一个怪物。请你给我一个答案和理由好吗?此外,如果这不是一个有效的实现,我如何修改它(不使用异步,因为我们仍然不存在)?请注意,Execute方法是从UI按钮处理程序触发的

谢谢,
-Mike

现在代码看起来,线程池线程只是用来重置事件处理程序,然后将其释放回池中。事件处理程序将在引发UpdateEvent事件的人的线程中运行,即第三方API的线程

为了避免这种情况,可以使用命令将事件转换为任务。在将复杂EAP操作公开为任务一节中的
中介绍了这一点。这样,事件处理程序将在线程池线程中异步运行,并且第三方的线程不会被阻止等待它

在您的情况下,您可以创建如下函数,以返回返回的任务:

public static Task<object> OnUpdateAsync(this IThridPartyApi dependency)
{
    var tcs=new TaskCompletionSource<object>();
    EventHandler handler=null;
    handler=(obj,args)=>
    {
        dependency.UpdateEvent-=handler;
        //extract the response here
        tcs.SetResult(response);
    }
    dependency.UpdateEvent+=handler;
    return tcs.Task;
}
公共静态任务OnUpdateAsync(此IThridPartyApi依赖项)
{
var tcs=new TaskCompletionSource();
EventHandler=null;
处理程序=(对象,参数)=>
{
dependency.UpdateEvent-=处理程序;
//在这里提取响应
设置结果(响应);
}
dependency.UpdateEvent+=处理程序;
返回tcs.Task;
}

您可以将返回类型从
object
更改为希望从第三方API接收的任何内容。

为什么您要实现自己的任务而不是使用TPL?它以一种更简单的方式解决了这些问题。此外,如果您希望事件处理程序异步启动(即使用
async
),您仍然需要使用TPL任务。但是,我可以使用TPL,但这是如何解决的呢?按照目前的代码方式,线程池线程只是设置了一个处理程序,然后就被释放了。处理程序由第三方的线程执行。这就是您想要的吗?问题是它是否已发布?是的,只要Execute返回