线程池线程&听取事件

时间:2013-12-12 10:03:16

标签: c#

我有一个已订阅事件的线程池线程,并且事件处理程序在另一个线程上被触发。我的问题是 - 线程池线程什么时候会被返回到池中,或者只要事件订阅处于活动状态就会留在那里?

例如:

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;
    }

在上面的例子中,让我们说RunTasks.Execute方法被多次调用(范围为100)并且事件处理程序被触发了50个并被延迟了接下来的50个 - 有多少活动线程将监听活动订阅?我在我的应用程序中有这个场景,所以试图确保我不是从这个实现中创建一个怪物。你能帮我解答一下这个问题吗?此外,如果这不是一个高效的实现,我怎么能修改它(不使用async,因为我们仍然没有)?请注意,Execute方法是从UI按钮处理程序触发的。

谢谢, -Mike

1 个答案:

答案 0 :(得分:0)

代码看起来的方式,ThreadPool线程仅用于重置事件处理程序,然后将其释放回池中。事件处理程序将在任何引发UpdateEvent事件的线程中运行,即第三方API的线程。

为避免这种情况,您可以使用TaskCompletionSource将事件转换为任务。 Exposing Complex EAP operations as Tasks部分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; } 中对此进行了描述。这样,事件处理程序将在ThreadPool线程中异步运行,并且不会阻止第三方的线程等待它。

在您的情况下,您可以创建一个类似以下的函数来返回返回的任务:

object

您可以将返回类型从{{1}}更改为您希望从第三方API获得的任何内容。