What is Task.RunSynchronously for?
Clash Royale CLAN TAG#URR8PPP
up vote
8
down vote
favorite
I just wonder what's the method for? In what kind of scenario I can use this method.
My initial thought is RunSynchronously
is for calling an async method and running that synchronously without causing a deadlock issue like what .wait()
does.
However, according to MSDN,
Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution
Why need a TaskScheduler here, if the task going to run on the calling thread?
c# multithreading asynchronous
 |Â
show 3 more comments
up vote
8
down vote
favorite
I just wonder what's the method for? In what kind of scenario I can use this method.
My initial thought is RunSynchronously
is for calling an async method and running that synchronously without causing a deadlock issue like what .wait()
does.
However, according to MSDN,
Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution
Why need a TaskScheduler here, if the task going to run on the calling thread?
c# multithreading asynchronous
3
Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
â Stefano d'Antonio
5 hours ago
2
It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only useRun
orRunSynchronously
with "cold" Tasks that haven't started yet.
â Damien_The_Unbeliever
5 hours ago
3
Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If youâÂÂre looking for best practices, move along; thereâÂÂs nothing to see here. So it seems legacy
â Liam
5 hours ago
2
MethodRunSynchronously
was created beforeasync await
flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as.StartNew()
it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the currentTaskScheduler
.
â Fabjan
4 hours ago
1
@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
â Panagiotis Kanavos
4 hours ago
 |Â
show 3 more comments
up vote
8
down vote
favorite
up vote
8
down vote
favorite
I just wonder what's the method for? In what kind of scenario I can use this method.
My initial thought is RunSynchronously
is for calling an async method and running that synchronously without causing a deadlock issue like what .wait()
does.
However, according to MSDN,
Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution
Why need a TaskScheduler here, if the task going to run on the calling thread?
c# multithreading asynchronous
I just wonder what's the method for? In what kind of scenario I can use this method.
My initial thought is RunSynchronously
is for calling an async method and running that synchronously without causing a deadlock issue like what .wait()
does.
However, according to MSDN,
Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution
Why need a TaskScheduler here, if the task going to run on the calling thread?
c# multithreading asynchronous
c# multithreading asynchronous
edited 5 hours ago
JoenSo
113
113
asked 5 hours ago
ValidfroM
1,34221635
1,34221635
3
Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
â Stefano d'Antonio
5 hours ago
2
It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only useRun
orRunSynchronously
with "cold" Tasks that haven't started yet.
â Damien_The_Unbeliever
5 hours ago
3
Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If youâÂÂre looking for best practices, move along; thereâÂÂs nothing to see here. So it seems legacy
â Liam
5 hours ago
2
MethodRunSynchronously
was created beforeasync await
flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as.StartNew()
it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the currentTaskScheduler
.
â Fabjan
4 hours ago
1
@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
â Panagiotis Kanavos
4 hours ago
 |Â
show 3 more comments
3
Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
â Stefano d'Antonio
5 hours ago
2
It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only useRun
orRunSynchronously
with "cold" Tasks that haven't started yet.
â Damien_The_Unbeliever
5 hours ago
3
Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If youâÂÂre looking for best practices, move along; thereâÂÂs nothing to see here. So it seems legacy
â Liam
5 hours ago
2
MethodRunSynchronously
was created beforeasync await
flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as.StartNew()
it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the currentTaskScheduler
.
â Fabjan
4 hours ago
1
@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
â Panagiotis Kanavos
4 hours ago
3
3
Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
â Stefano d'Antonio
5 hours ago
Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
â Stefano d'Antonio
5 hours ago
2
2
It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use
Run
or RunSynchronously
with "cold" Tasks that haven't started yet.â Damien_The_Unbeliever
5 hours ago
It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use
Run
or RunSynchronously
with "cold" Tasks that haven't started yet.â Damien_The_Unbeliever
5 hours ago
3
3
Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If youâÂÂre looking for best practices, move along; thereâÂÂs nothing to see here. So it seems legacy
â Liam
5 hours ago
Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If youâÂÂre looking for best practices, move along; thereâÂÂs nothing to see here. So it seems legacy
â Liam
5 hours ago
2
2
Method
RunSynchronously
was created before async await
flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew()
it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler
.â Fabjan
4 hours ago
Method
RunSynchronously
was created before async await
flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew()
it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler
.â Fabjan
4 hours ago
1
1
@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
â Panagiotis Kanavos
4 hours ago
@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
â Panagiotis Kanavos
4 hours ago
 |Â
show 3 more comments
2 Answers
2
active
oldest
votes
up vote
7
down vote
accepted
RunSynchronously
delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).
I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.
RunSynchronously
asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.
The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).
RunSynchronously
will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).
This code may clarify the different behaviour:
Wait
and Result
don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start
and Wait
to RunSynchronously
:
class Scheduler : TaskScheduler
protected override void QueueTask(Task task) =>
Console.WriteLine("QueueTask");
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
Console.WriteLine("TryExecuteTaskInline");
return false;
protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();
static class Program
static void Main()
var taskToStart = new Task(() => );
var taskToRunSynchronously = new Task(() => );
taskToStart.Start(new Scheduler());
taskToRunSynchronously.RunSynchronously(new Scheduler());
If you try and comment Start or RunSynchronously
and run the code, you will see that Start
tries and queue the task to the scheduler while RunSynchronously
will try and execute it inline and if failing (return false), it will just queue it.
add a comment |Â
up vote
4
down vote
First let's have a look into this code:
public async static Task<int> MyAsyncMethod()
await Task.Delay(100);
return 100;
//Task.Delay(5000).RunSynchronously(); // bang
//Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
// MyAsyncMethod().RunSynchronously(); // bang
var t = new Task(() => Thread.Sleep(5000));
t.RunSynchronously(); // works
In this example we've tried to invoke RunSynchronously
on task that:
- Returns other Task with result (promise task)
- Is a 'hot' task
- Another promise task created by
async await
- 'Cold' task with delegate
What statuses will they have after creation ?
- Waiting for activation
- WaitingToRun
- WaitingForActivation
- Created
All 'hot' tasks are created with status WaitingForActivation
or WaitingToRun
and are associated with a task scheduler.
Method RunSynchronously
only knows how to work with 'cold' tasks that contain delegate and that have status of Created
.
Conclusion:
The method RunSynchronously
had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.
In case we need a 'cold' task with custom TaskScheduler
then method RunSynchronously
might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.
For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult()
. As a bonus it will return original exception and not AggregateException
.
It's probably worth noting thatThread
has (basically) been superseded withTask
(Task.Delay()
) soThread.Sleep
could be considered legacy too now. Which is why it works with the legacyRunSynchronously
â Liam
4 hours ago
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
RunSynchronously
delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).
I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.
RunSynchronously
asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.
The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).
RunSynchronously
will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).
This code may clarify the different behaviour:
Wait
and Result
don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start
and Wait
to RunSynchronously
:
class Scheduler : TaskScheduler
protected override void QueueTask(Task task) =>
Console.WriteLine("QueueTask");
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
Console.WriteLine("TryExecuteTaskInline");
return false;
protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();
static class Program
static void Main()
var taskToStart = new Task(() => );
var taskToRunSynchronously = new Task(() => );
taskToStart.Start(new Scheduler());
taskToRunSynchronously.RunSynchronously(new Scheduler());
If you try and comment Start or RunSynchronously
and run the code, you will see that Start
tries and queue the task to the scheduler while RunSynchronously
will try and execute it inline and if failing (return false), it will just queue it.
add a comment |Â
up vote
7
down vote
accepted
RunSynchronously
delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).
I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.
RunSynchronously
asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.
The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).
RunSynchronously
will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).
This code may clarify the different behaviour:
Wait
and Result
don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start
and Wait
to RunSynchronously
:
class Scheduler : TaskScheduler
protected override void QueueTask(Task task) =>
Console.WriteLine("QueueTask");
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
Console.WriteLine("TryExecuteTaskInline");
return false;
protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();
static class Program
static void Main()
var taskToStart = new Task(() => );
var taskToRunSynchronously = new Task(() => );
taskToStart.Start(new Scheduler());
taskToRunSynchronously.RunSynchronously(new Scheduler());
If you try and comment Start or RunSynchronously
and run the code, you will see that Start
tries and queue the task to the scheduler while RunSynchronously
will try and execute it inline and if failing (return false), it will just queue it.
add a comment |Â
up vote
7
down vote
accepted
up vote
7
down vote
accepted
RunSynchronously
delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).
I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.
RunSynchronously
asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.
The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).
RunSynchronously
will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).
This code may clarify the different behaviour:
Wait
and Result
don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start
and Wait
to RunSynchronously
:
class Scheduler : TaskScheduler
protected override void QueueTask(Task task) =>
Console.WriteLine("QueueTask");
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
Console.WriteLine("TryExecuteTaskInline");
return false;
protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();
static class Program
static void Main()
var taskToStart = new Task(() => );
var taskToRunSynchronously = new Task(() => );
taskToStart.Start(new Scheduler());
taskToRunSynchronously.RunSynchronously(new Scheduler());
If you try and comment Start or RunSynchronously
and run the code, you will see that Start
tries and queue the task to the scheduler while RunSynchronously
will try and execute it inline and if failing (return false), it will just queue it.
RunSynchronously
delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).
I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.
RunSynchronously
asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.
The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).
RunSynchronously
will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).
This code may clarify the different behaviour:
Wait
and Result
don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start
and Wait
to RunSynchronously
:
class Scheduler : TaskScheduler
protected override void QueueTask(Task task) =>
Console.WriteLine("QueueTask");
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
Console.WriteLine("TryExecuteTaskInline");
return false;
protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();
static class Program
static void Main()
var taskToStart = new Task(() => );
var taskToRunSynchronously = new Task(() => );
taskToStart.Start(new Scheduler());
taskToRunSynchronously.RunSynchronously(new Scheduler());
If you try and comment Start or RunSynchronously
and run the code, you will see that Start
tries and queue the task to the scheduler while RunSynchronously
will try and execute it inline and if failing (return false), it will just queue it.
edited 4 hours ago
Liam
15.5k1575125
15.5k1575125
answered 4 hours ago
Stefano d'Antonio
3,60011632
3,60011632
add a comment |Â
add a comment |Â
up vote
4
down vote
First let's have a look into this code:
public async static Task<int> MyAsyncMethod()
await Task.Delay(100);
return 100;
//Task.Delay(5000).RunSynchronously(); // bang
//Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
// MyAsyncMethod().RunSynchronously(); // bang
var t = new Task(() => Thread.Sleep(5000));
t.RunSynchronously(); // works
In this example we've tried to invoke RunSynchronously
on task that:
- Returns other Task with result (promise task)
- Is a 'hot' task
- Another promise task created by
async await
- 'Cold' task with delegate
What statuses will they have after creation ?
- Waiting for activation
- WaitingToRun
- WaitingForActivation
- Created
All 'hot' tasks are created with status WaitingForActivation
or WaitingToRun
and are associated with a task scheduler.
Method RunSynchronously
only knows how to work with 'cold' tasks that contain delegate and that have status of Created
.
Conclusion:
The method RunSynchronously
had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.
In case we need a 'cold' task with custom TaskScheduler
then method RunSynchronously
might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.
For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult()
. As a bonus it will return original exception and not AggregateException
.
It's probably worth noting thatThread
has (basically) been superseded withTask
(Task.Delay()
) soThread.Sleep
could be considered legacy too now. Which is why it works with the legacyRunSynchronously
â Liam
4 hours ago
add a comment |Â
up vote
4
down vote
First let's have a look into this code:
public async static Task<int> MyAsyncMethod()
await Task.Delay(100);
return 100;
//Task.Delay(5000).RunSynchronously(); // bang
//Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
// MyAsyncMethod().RunSynchronously(); // bang
var t = new Task(() => Thread.Sleep(5000));
t.RunSynchronously(); // works
In this example we've tried to invoke RunSynchronously
on task that:
- Returns other Task with result (promise task)
- Is a 'hot' task
- Another promise task created by
async await
- 'Cold' task with delegate
What statuses will they have after creation ?
- Waiting for activation
- WaitingToRun
- WaitingForActivation
- Created
All 'hot' tasks are created with status WaitingForActivation
or WaitingToRun
and are associated with a task scheduler.
Method RunSynchronously
only knows how to work with 'cold' tasks that contain delegate and that have status of Created
.
Conclusion:
The method RunSynchronously
had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.
In case we need a 'cold' task with custom TaskScheduler
then method RunSynchronously
might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.
For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult()
. As a bonus it will return original exception and not AggregateException
.
It's probably worth noting thatThread
has (basically) been superseded withTask
(Task.Delay()
) soThread.Sleep
could be considered legacy too now. Which is why it works with the legacyRunSynchronously
â Liam
4 hours ago
add a comment |Â
up vote
4
down vote
up vote
4
down vote
First let's have a look into this code:
public async static Task<int> MyAsyncMethod()
await Task.Delay(100);
return 100;
//Task.Delay(5000).RunSynchronously(); // bang
//Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
// MyAsyncMethod().RunSynchronously(); // bang
var t = new Task(() => Thread.Sleep(5000));
t.RunSynchronously(); // works
In this example we've tried to invoke RunSynchronously
on task that:
- Returns other Task with result (promise task)
- Is a 'hot' task
- Another promise task created by
async await
- 'Cold' task with delegate
What statuses will they have after creation ?
- Waiting for activation
- WaitingToRun
- WaitingForActivation
- Created
All 'hot' tasks are created with status WaitingForActivation
or WaitingToRun
and are associated with a task scheduler.
Method RunSynchronously
only knows how to work with 'cold' tasks that contain delegate and that have status of Created
.
Conclusion:
The method RunSynchronously
had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.
In case we need a 'cold' task with custom TaskScheduler
then method RunSynchronously
might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.
For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult()
. As a bonus it will return original exception and not AggregateException
.
First let's have a look into this code:
public async static Task<int> MyAsyncMethod()
await Task.Delay(100);
return 100;
//Task.Delay(5000).RunSynchronously(); // bang
//Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
// MyAsyncMethod().RunSynchronously(); // bang
var t = new Task(() => Thread.Sleep(5000));
t.RunSynchronously(); // works
In this example we've tried to invoke RunSynchronously
on task that:
- Returns other Task with result (promise task)
- Is a 'hot' task
- Another promise task created by
async await
- 'Cold' task with delegate
What statuses will they have after creation ?
- Waiting for activation
- WaitingToRun
- WaitingForActivation
- Created
All 'hot' tasks are created with status WaitingForActivation
or WaitingToRun
and are associated with a task scheduler.
Method RunSynchronously
only knows how to work with 'cold' tasks that contain delegate and that have status of Created
.
Conclusion:
The method RunSynchronously
had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.
In case we need a 'cold' task with custom TaskScheduler
then method RunSynchronously
might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.
For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult()
. As a bonus it will return original exception and not AggregateException
.
edited 3 hours ago
answered 4 hours ago
Fabjan
8,76421438
8,76421438
It's probably worth noting thatThread
has (basically) been superseded withTask
(Task.Delay()
) soThread.Sleep
could be considered legacy too now. Which is why it works with the legacyRunSynchronously
â Liam
4 hours ago
add a comment |Â
It's probably worth noting thatThread
has (basically) been superseded withTask
(Task.Delay()
) soThread.Sleep
could be considered legacy too now. Which is why it works with the legacyRunSynchronously
â Liam
4 hours ago
It's probably worth noting that
Thread
has (basically) been superseded with Task
(Task.Delay()
) so Thread.Sleep
could be considered legacy too now. Which is why it works with the legacy RunSynchronously
â Liam
4 hours ago
It's probably worth noting that
Thread
has (basically) been superseded with Task
(Task.Delay()
) so Thread.Sleep
could be considered legacy too now. Which is why it works with the legacy RunSynchronously
â Liam
4 hours ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52759608%2fwhat-is-task-runsynchronously-for%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
â Stefano d'Antonio
5 hours ago
2
It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use
Run
orRunSynchronously
with "cold" Tasks that haven't started yet.â Damien_The_Unbeliever
5 hours ago
3
Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If youâÂÂre looking for best practices, move along; thereâÂÂs nothing to see here. So it seems legacy
â Liam
5 hours ago
2
Method
RunSynchronously
was created beforeasync await
flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as.StartNew()
it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the currentTaskScheduler
.â Fabjan
4 hours ago
1
@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
â Panagiotis Kanavos
4 hours ago