Got a question from VSIP partner Patrick today and wanted to pass it along. Before I do that though, let me once again apologize for not blogging like you want me to. I will strive to do better. I promise.
So, here's the question: What's the deal with IVsThreadPool?
Here's the answer:
The SVsThreadPool service is available to schedule background tasks in a thread pool managed by VS. This is useful for long running tasks that need to get done, but can be done without the user interacting.
First, this is for native code only. If you want managed code then the .net framework’s thread pool is fine. Second, you should make no assumptions about COM threading or CoInitialize settings. Be careful accessing data or calling methods on COM objects where the apartment may need to be switched away from the free thread that the thread pool gives you for your task. This can cause race conditions or data corruption. My recommendation is to have the background task avoid interaction with other threads and objects as much as possible. Do nothing or as little as you can with other COM objects directly and try to use Win32 methods to access shared resources. This is a conservative approach, but it simplifies things tremendously.
The service is designed to have two types of callbacks. First is a callback whenever a thread is available. This is useful for general background work. Once your task exits, then it is done forever and you can reschedule it or another task if you need more background work done. The second is a handle-activated callback where your task method is called whenever the handle you supply is signaled. Once your task exits, the handle is checked again and you will be called again if/when it is signaled. This is useful for Win32 WaitForSingleObject style background work. You have to explicitly shutdown VS or unschedule your task for this type to go away. Be careful to unschedule the task before closing the handle. Once the task is scheduled the handle is used in a WaitForMultipleObjects call on the background thread so if you close it on another thread then that can cause problems (perhaps crashes).
As for setting the event passed to you, you should not set it. It is set by the thread pool service in order to inform you that the thread pool is shutting down. It is meant as a ‘please exit the building now’ kind of signal. If you set it yourself, then that might cause problem, but it is doubtful. For long running tasks, the task should periodically check the state of the handle passed to you to determine if it is signaled. If it is signaled, then the thread pool is terminating and all tasks should exit immediately (basic terminate early work should be done (like closing a file handle to get it to flush data to it, for instance, but no other work should be performed).
You'll find some details in the VSSHELL80.IDL file in the EnvSDK part of the VSIP SKU.
P.S. Check out the MSDN Forum on VS Extensibility. I’m trying to get myself and more folks to hang out there to answer questions just like this one:
P.P.S I can't wait to tell you all about some exciting changes to the VSIP SKU in the near future. Watch for announcements on the VS Extensibility portal.