How to create a task (TPL) running a STA thread?
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);
Related videos on Youtube
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, 2022Comments
-
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.
-
Mrchief almost 10 yearsFor any future visitors who come looking for the real intent of the question: - Using
StaTaskScheduler
(guide) as pointed in this answer - DIY version: stackoverflow.com/questions/16720496/…
-
-
dudeNumber4 about 12 yearsJust 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 about 12 yearsThanks for this, I was trying
TaskScheduler.Current
(from within a WinForms button event handler), couldn't understand why it wasn't working... -
Josh Sutterfield about 10 yearsAs 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 almost 10 yearsSo shouldn't this question's title be edited to better reflect its intention?
-
David about 8 yearsOr 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 almost 8 yearspublic 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 almost 8 yearswhere 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 over 3 yearsThe
ContinueWith
and theDispatcher
are considered old-school approaches after the advent of async/await. I would avoid using them for new development (in general).