Skip to main content
error
Source Link
svick
  • 10.2k
  • 1
  • 40
  • 54

It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

EDIT: Probably the simplest way to convert your current code to Tasks would be using TaskCompletionSource. Simply call TaskCompletionSource.SetResult() instead of invoking an event.

But another option might be something like this:

class Decoder : IDecoder { // initialize with a completed Task Task previous = Task.FromResult(true); public Task<DecodeResult> DecodeAsync(parameters) { var result = DecodeAsyncInternal(parameters); previous = result; return result; } private async Task<DecodeResult> DecodeAsyncInternal(parameters) { await previous; return await Task.Run(() => ActualDecode(parameters)); } } 

This won't guarantee that all decoding is done on the same thread, but it does guarantee that the jobs will be executed one after the other.

Also, this code is not thread-safe: it won't work correctly if call DecodeAsync() at the same time from multiple threads. If you need that, use a lock.

It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

EDIT: Probably the simplest way to convert your current code to Tasks would be using TaskCompletionSource. Simply call TaskCompletionSource.SetResult() instead of invoking an event.

But another option might be something like this:

class Decoder : IDecoder { // initialize with a completed Task Task previous = Task.FromResult(true); public Task<DecodeResult> DecodeAsync(parameters) { var result = DecodeAsyncInternal(parameters); previous = result; return result; } private async Task<DecodeResult> DecodeAsyncInternal(parameters) { await previous; await Task.Run(() => ActualDecode(parameters)); } } 

This won't guarantee that all decoding is done on the same thread, but it does guarantee that the jobs will be executed one after the other.

Also, this code is not thread-safe: it won't work correctly if call DecodeAsync() at the same time from multiple threads. If you need that, use a lock.

It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

EDIT: Probably the simplest way to convert your current code to Tasks would be using TaskCompletionSource. Simply call TaskCompletionSource.SetResult() instead of invoking an event.

But another option might be something like this:

class Decoder : IDecoder { // initialize with a completed Task Task previous = Task.FromResult(true); public Task<DecodeResult> DecodeAsync(parameters) { var result = DecodeAsyncInternal(parameters); previous = result; return result; } private async Task<DecodeResult> DecodeAsyncInternal(parameters) { await previous; return await Task.Run(() => ActualDecode(parameters)); } } 

This won't guarantee that all decoding is done on the same thread, but it does guarantee that the jobs will be executed one after the other.

Also, this code is not thread-safe: it won't work correctly if call DecodeAsync() at the same time from multiple threads. If you need that, use a lock.

added 1085 characters in body
Source Link
svick
  • 10.2k
  • 1
  • 40
  • 54

It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

EDIT: Probably the simplest way to convert your current code to Tasks would be using TaskCompletionSource. Simply call TaskCompletionSource.SetResult() instead of invoking an event.

But another option might be something like this:

class Decoder : IDecoder { // initialize with a completed Task Task previous = Task.FromResult(true); public Task<DecodeResult> DecodeAsync(parameters) { var result = DecodeAsyncInternal(parameters); previous = result; return result; } private async Task<DecodeResult> DecodeAsyncInternal(parameters) { await previous; await Task.Run(() => ActualDecode(parameters)); } } 

This won't guarantee that all decoding is done on the same thread, but it does guarantee that the jobs will be executed one after the other.

Also, this code is not thread-safe: it won't work correctly if call DecodeAsync() at the same time from multiple threads. If you need that, use a lock.

It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

EDIT: Probably the simplest way to convert your current code to Tasks would be using TaskCompletionSource. Simply call TaskCompletionSource.SetResult() instead of invoking an event.

But another option might be something like this:

class Decoder : IDecoder { // initialize with a completed Task Task previous = Task.FromResult(true); public Task<DecodeResult> DecodeAsync(parameters) { var result = DecodeAsyncInternal(parameters); previous = result; return result; } private async Task<DecodeResult> DecodeAsyncInternal(parameters) { await previous; await Task.Run(() => ActualDecode(parameters)); } } 

This won't guarantee that all decoding is done on the same thread, but it does guarantee that the jobs will be executed one after the other.

Also, this code is not thread-safe: it won't work correctly if call DecodeAsync() at the same time from multiple threads. If you need that, use a lock.

Source Link
svick
  • 10.2k
  • 1
  • 40
  • 54

It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.