How to create a task (TPL) running a STA thread?

63,110

You can use the TaskScheduler.FromCurrentSynchronizationContext Method to get a TaskScheduler for the current synchronization context (which is the WPF dispatcher when you're running a WPF application).

Then use the ContinueWith overload that accepts a TaskScheduler:

var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Factory.StartNew(...)
            .ContinueWith(r => AddControlsToGrid(r.Result), scheduler);
Share:
63,110

Related videos on Youtube

Michel Triana
Author by

Michel Triana

I'm an Entrepreneur, Computer Scientist and a troublemaker. I've co-founded a couple of startups, and now lead the product, design and engineering of the R&D group at JM Family Enterprises Inc. I enjoy making things and building software. Not only apps, but the engines and frameworks they run on. The things I build must have a purpose, and a good one. Before accepting any job or project, I must come to accept/create a vision and direction in terms of positive impact in the world and society. I'm a pragmatic business man, scientist, and thinker. Sometimes, I'm told by people no longer working next to me, a little too pragmatic. I have no time to spare and there is no dull moment in my life, because I like to squeeze the orange all the way. Other than that, I'm a naturally fast-talking-coherent-cursing mthrfckr, which means I will not apologize to anyone for speaking to loud, or being a well-educated nuclear-passionate hot-blooded guy. FIND ME HERE: My Blog | Twitter | Google+ | Facebook | LinkedIn Specialties: - Leadership, Project Management & Team Building, SDLC, Business Analysis, Design Patterns, Scrum. - Framework Development, CRM, CMS, SRM, XRM, POS, Financial and Accounting Integration and ERP system development. - .Net Framework. SQL Server, Web Services, MOSS, SOA, Web and WinApps, Win API, WCF, WF, WPF, SSRS, Crystal. C#, ASP.NET, XML, JavaScript, HTML, CSS.

Updated on July 05, 2022

Comments

  • Michel Triana
    Michel Triana almost 2 years

    Using Thread is pretty straightforward

     Thread thread = new Thread(MethodWhichRequiresSTA);
     thread.SetApartmentState(ApartmentState.STA);  
    

    How to accomplish the same using Tasks in a WPF application? Here is some code:

    Task.Factory.StartNew
      (
        () => 
        {return "some Text";}
      )
       .ContinueWith(r => AddControlsToGrid(r.Result));  
    

    I'm getting an InvalidOperationException with

    The calling thread must be STA, because many UI components require this.

  • dudeNumber4
    dudeNumber4 about 12 years
    Just to be clear; only the lambda within the ContinueWith method will run with the proper context, not what runs in the main task lambda.
  • tina Miller
    tina Miller about 12 years
    Thanks for this, I was trying TaskScheduler.Current (from within a WinForms button event handler), couldn't understand why it wasn't working...
  • Josh Sutterfield
    Josh Sutterfield about 10 years
    As a point of clarification, there is also an overload for the instance method Task.Start() which takes a TaskScheduler. The details of the question make it clear we're more interested in the continuation case, but the more general question of how to run a Task on an STA thread is not limited to only that case. I wrongly assumed at first I would need continue from an empty "fudge" task in order to run my desired STA task.
  • Mrchief
    Mrchief almost 10 years
    So shouldn't this question's title be edited to better reflect its intention?
  • David
    David about 8 years
    Or broken down into two. "How do i start a task on an STA thread" and "How do i continue a task on an STA thread".
  • Juan Pablo Garcia Coello
    Juan Pablo Garcia Coello almost 8 years
    public static Task<string> ShowOpenFolderPicker() { var scheduler = TaskScheduler.FromCurrentSynchronizationContext(); var tokensource = new CancellationTokenSource(); return Task.Factory.StartNew(Show,tokensource.Token, TaskCreationOptions.None,scheduler); }
  • Juan Pablo Garcia Coello
    Juan Pablo Garcia Coello almost 8 years
    where for instance: private static String Show() { var dialog = new System.Windows.Forms.FolderBrowserDialog(); dialog.ShowNewFolderButton = true; var result = dialog.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { return dialog.SelectedPath; } return null; }
  • Theodor Zoulias
    Theodor Zoulias over 3 years
    The ContinueWith and the Dispatcher are considered old-school approaches after the advent of async/await. I would avoid using them for new development (in general).