I have a WinForms application, and I want to use the Windows.Forms.OpenFileDialog
, which requires an STA thread. It works fine with threads, but what about tasks?
Related question, but didn't find a solution there: How to create a task (TPL) running a STA thread?
Here's an example of what I'm trying to achieve (mainly tried what is done in the related question above):
public async Task<string> TestFileDialogAsync()
{
string outFile = "no file";
await Task.Factory.StartNew(() =>
{
Console.WriteLine($"Thread apartment: {Thread.CurrentThread.ApartmentState}");
// prints MTA
try
{
using (OpenFileDialog myDialog = new OpenFileDialog())
{
myDialog.Title = "Choose a file...";
myDialog.Filter = "All Files|*.*";
if (myDialog.ShowDialog() == DialogResult.OK) // no dialog ever shown
{
outFile = myDialog.FileName;
}
}
}
catch (Exception e) // no exception thrown - assuming task blocks in ShowDialog
{
Console.WriteLine($"Exception occured: {e.Message}");
throw;
}
}, CancellationToken.None, TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
return outFile;
}
This is then called as:
string chosenFile = await TestFileDialogAsync();
In the question I've linked something similar is marked as answer, but this does not work for me.
I don't understand how TaskScheduler.FromCurrentSynchronizationContext() is supposed to force a task to run on a STA thread, as specified in the related question I've linked. (maybe the calling thread there was an STA thread to begin with, but the task was starting in MTA, and that is why this works?)
So how do I forcibly start a task on STA apartment state, so that I can use components that require it in my application?