public static void Execute(Process process)
        {
            #if false
            if (Thread.CurrentThread.IsBackground)
                throw new Exception("Should not run in background!");
            int fgThreadId = Thread.CurrentThread.ManagedThreadId;
            #endif

            if (logger.IsDebugEnabled)
                logger.Debug("Running process: " + process.Description);

            // run that process
            BackgroundWorker bgWorker = new BackgroundWorker();
            ErrorHolder errorHolder = new ErrorHolder();
            bgWorker.DoWork += delegate(object sender, DoWorkEventArgs e)
            {
            #if DEBUG
                if (Thread.CurrentThread.IsBackground == false)
                    throw new Exception("Should run in background!");
            #endif

            #if DONT_CATCH_EXCEPTION
                process.Run(sender, e);
            #else
                // here we catch exceptions because otherwise, Visual Studio breaks,
                // even though the BackgroundWorker itself catches the exceptions!
                try
                {
                    process.Run(sender, e);
                }
                catch (Exception error)
                {
                    errorHolder.Error = error;
                }
            #endif
            };
            bgWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
            {
            #if false
                if (Thread.CurrentThread.IsBackground)
                    throw new Exception("Should not run in background!");
                if (Thread.CurrentThread.ManagedThreadId != fgThreadId)
                    throw new Exception("RunWorkerCompleted called in another thread");
            #endif

                // replace the args with one containing the caught error (if any)
                e = new RunWorkerCompletedEventArgs(e.Result, errorHolder.Error, e.Cancelled);

                if (logger.IsDebugEnabled)
                    logger.Debug("Done running process: " + process.Description);
                if (e.Error != null)
                    LoggingHelper.LogError(logger, e.Error);

                process.OnCompleted(sender, e);
            };
            bgWorker.RunWorkerAsync();
        }
        public void UpdateProjectList(Server server)
        {
            this.server = server;
            #if SYNCRHONOUS
            List<Project> dataSource = new List<Project>();

            if (server != null)
            {
                IList<Project> projects = jenkinsService.LoadProjects(server);
                foreach (Project project in projects)
                    dataSource.Add(project);
            }

            SetProjectsDataSource(dataSource);
            #else
            // clear the view
            projectsGridControl.DataSource = null;

            if (server == null)
                return;

            // disable the window, change the cursor, update the status
            Cursor.Current = Cursors.WaitCursor;
            Enabled = false;
            string status = string.Format(JenkinsTrayResources.LoadingProjects_FormatString, server.Url);
            Controller.SetStatus(status, true);

            // run the process in background
            Process process = new Process("Loading project " + server.Url);
            IList<Project> projects = null;
            process.DoWork += delegate
            {
                projects = JenkinsService.LoadProjects(server);
            };
            process.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
            {
                string endStatus = "";

                if (e.Error == null)
                {
                    var dataSource = new List<Project>();
                    foreach (Project project in projects)
                        dataSource.Add(project);
                    SetProjectsDataSource(dataSource);
                }
                else
                {
                    endStatus = string.Format(JenkinsTrayResources.FailedLoadingProjects_FormatString, server.Url);
                }

                // enable the window, change the cursor, update the status
                Enabled = true;
                Cursor.Current = Cursors.Default;
                Controller.SetStatus(endStatus, false);
            };
            BackgroundProcessExecutor.Execute(process);
            #endif
        }