VS2012 IVsSolution.GetUniqueNameOfProject problems
-
Thursday, September 20, 2012 11:41 AM
Hi,
Calling IVsSolution.GetUniqueNameOfProject from a worker thread fails. It works calling the method from the main thread. Same code worked just fine on VS2012.
Has anyone encountered this problem? Are there any changes to this method in Vs2012
Thanks
All Replies
-
Thursday, September 20, 2012 5:31 PMModerator
How does it fail exactly? That is a pretty vague :)
Ryan
-
Friday, September 21, 2012 5:52 AM
Hi,
It returns E_FAIL even if it works fine on main thread.
-
Friday, September 21, 2012 3:03 PMModerator
Are you sure the project is completely loaded? In 2012 there is asynchronous solution load, so not all projects are immediately loaded as they were in the past. I don't think this has to do with foreground/background thread per-se. This is a COM STA object, so when you call it on a background thread it uses a proxy and executes the actual code on the UI thread, so it always runs on the UI thread. Though there are likely timing differences between your two scenarios. Do you have a repro?
-
Monday, September 24, 2012 8:11 AM
Yes the project is loaded.
<<This is a COM STA object, so when you call it on a background thread it uses a proxy and executes the actual code on the UI thread, so it always runs on the UI thread.>>
Then it should work. Calling it on the UI thread works. It looks that the project list for the solution is not properly loaded on the secondary thread.
<<Do you have a repro?>>
I'm afraid not. I have a custom project based on this http://mpfproj10.codeplex.com/. I will try to reproduce it on a simple scenario
-
Tuesday, September 25, 2012 9:57 AM
Have managed to reproduce this issue on a simpler use case. Project.UniqueName throws an exception.
Thanks
private void MenuItemCallback(object sender, EventArgs e) { //Create worker thread. Company.Execute execThread = new Company.Execute(); //Add event handler execThread.ExecuteCompleted += (src, arg) => { Debug.WriteLine("Executing event raised by thread"); EnvDTE.DTE dte = (EnvDTE.DTE)GetService(typeof(EnvDTE.DTE)); EnvDTE.Solution solution = dte.Solution; string fullname = solution.FullName; Debug.WriteLine("Solution full name" + fullname ); foreach ( EnvDTE.Project project in solution.Projects ) { //Throws System.Runtime.InteropServices.COMException exception. string uniqueName = project.UniqueName; Debug.WriteLine("Project unique name" + uniqueName); } }; //Start the thread execThread.Start(); }
namespace Company { public class Execute { public void Start() { Thread execThread = new Thread(() => { try { //Counting from 1 to 1000 int i = 0; do { i++; } while ( i <= 1000 ); } catch (System.Exception ex) { Debug.WriteLine(ex.Message); } finally { OnExecuteCompleted(); } }); // Start thread try { execThread.SetApartmentState(ApartmentState.STA); execThread.Start(); } catch (System.Exception) { OnExecuteCompleted(); } } public event EventHandler ExecuteCompleted; protected virtual void OnExecuteCompleted() { try { if (null != ExecuteCompleted) { EventArgs args = new EventArgs(); ExecuteCompleted.Invoke(this, EventArgs.Empty); } } catch { Debug.WriteLine("An exception occurred"); } } } }
- Edited by Ciprian Burca Tuesday, September 25, 2012 10:00 AM
-
Tuesday, September 25, 2012 8:08 PMModerator
There is no "project list for the secondary thread", as I said your call goes through a COM proxy and thus always executes on the UI thread. I will have to debug into the repro to see where the E_FAIL is coming from, but I won't be able to do that for a couple of days as I am out of town at a conference.
Ryan

