Reputation: 36048
I know there is a similar question at: ContinueWith a Task on the Main thread
but that question is more toward wpf and I cannot seeem to make it work on a console application.
I want to execute a method on a different thread and when that method is completed I want to keep execution on the main thread. I do not want to join method. anyways here is what I have:
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.Name = "MAIN";
DoWork(x =>
{
Console.Write("Method successfully executed. Executing callback method in thread:" +
"\n" + Thread.CurrentThread.Name);
});
Console.Read();
}
static void DoWork(Action<bool> onCompleteCallback)
{
Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing
Task doWork = new Task(() =>
{
Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing
Thread.Sleep(4000);
});
Action<Task> onComplete = (task) =>
{
onCompleteCallback(true);
};
doWork.Start();
// this line gives an error!
doWork.ContinueWith(onComplete, TaskScheduler.FromCurrentSynchronizationContext());
}
}
How can I execute the onCompleteCallback method on the main thread?
Upvotes: 5
Views: 7497
Reputation: 564403
but that question is more toward wpf and I cannot seeem to make it work on a console application.
You can't do this (without a lot of work) in a Console application. The mechanisms built into the TPL for marshaling the call back onto a thread all rely on the thread having an installed SynchronizationContext
. This typically gets installed by the user interface framework (ie: Application.Run
in Windows Forms, or in WPF's startup code, etc).
In most cases, it works because the main thread has a message loop, and the framework can post a message onto the message loop, which then gets picked up and runs the code. With a console application, it's just a "raw" thread - there is no message loop where a message can be placed.
You could, of course, install your own context, but that's going to be adding a lot of overhead that is likely not necessary.
In a console application, "getting back" to the console thread is typically not necessary. Normally, you'd just wait on the task, ie:
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.Name = "MAIN";
Task workTask = DoWork();
workTask.Wait(); // Just wait, and the thread will continue
// when the work is complete
Console.Write("Method successfully executed. Executing callback method in thread:" +
"\n" + Thread.CurrentThread.Name);
Console.Read();
}
static Task DoWork()
{
Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing
Task doWork = new Task(() =>
{
Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing
Thread.Sleep(4000);
});
doWork.Start();
return doWork;
}
}
Upvotes: 5