If my interface must return Task what is the best way to have a no-operation implementation?
Today, I would recommend using Task.CompletedTask to accomplish this.
Pre .net 4.6:
Using Task.FromResult(0)
or Task.FromResult<object>(null)
will incur less overhead than creating a Task
with a no-op expression. When creating a Task
with a result pre-determined, there is no scheduling overhead involved.
Should all interfaces be re-written to return TaskResult?
This design issue is parallel with IDisposable
. When you are writing an interface, you have to know whether it's "likely" that derived types will need IDisposable
, and derive from it if they will. Non-disposable types like test stubs just implement a noop Dispose
.
Similarly, when you are writing an interface, you have to know whether it's "likely" that derived types will use asynchronous implementations.
Note that the question for derived types is: "Will the implementation be naturally asynchronous?", not "Will the implementation be fast?". Speed has nothing to do with it. The only thing you should consider is whether the implementations may be naturally-asynchronous (i.e., using I/O or other asynchronous methods).
When you write an interface, there's usually one (or a small number) of implementations that you have in mind; I recommend that you just consider those when deciding to make the interface methods asynchronous. You could go extreme and just make every interface method asynchronous, but that would be like using IDisposable
everywhere - not a pattern that I'd recommend.
So, I would say that if your (current) implementations are all synchronous for a particular method, then make that method synchronous; otherwise, make it asynchronous.
As you noted, an asynchronous method signature technically means that the implementation may be asynchronous. Test stubs and the like can use Task.FromResult
to implement an asynchronous signature synchronously. Personally, I think this is perfectly acceptable for stub implementations; but I would not recommend making a method async "just in case", when all current implementations are synchronous.
Also, I'm strongly against having both signatures. This would require implementors to wrap sync-over-async or async-over-sync, neither of which is ideal.
Is it better to return an empty task or null? c#
if it finds no results is it better to return an empty task or null?
There's a couple things to consider here:
First, you should never return a null Task
. In the async
world, a null
task just doesn't make sense. Task
represents the execution of the asynchronous method, so for an asynchronous method to return a null
task is like telling the calling code "you didn't really just call this method" when of course it did.
So, a Task
/Task<T>
returned from a method should never, ever be null
. However, you still have the option of returning a null
value inside a regular task. That is up to you.
with tasks i am unsure which is best.
The task is just a wrapper. The underlying logic is still the same. Think of how this method would look if it were synchronous; would your return type be int
and return 0
if nothing was found, or would your return type be int?
and return null
if nothing was found? After making that choice for a synchronous method, then wrap it in Task<T>
for the asynchronous method.
As a final note, I must say:
- Do not ever, ever use the
Task
constructor. - Avoid
Task<T>.Result
; useawait
instead. - Do not use
ContinueWith
; useawait
instead.
Your method can be drastically simplified:
public virtual async Task<int> GetJobRunIdAsync(int jobId)
{
var jobMonRequest = ...;
var jobMonResponse = await Client.jobmonAsync(jobMonRequest);
if (jobMonResponse == null)
return 0;
if (jobMonResponse.jobrun.Length > 1)
throw new Exception("More than one job found, Wizards are abound.");
return jobMonResponse.jobrun.Single().id;
}
Or, if you want to return a value (not task) of null
:
public virtual async Task<int?> GetJobRunIdAsync(int jobId)
{
var jobMonRequest = ...;
var jobMonResponse = await Client.jobmonAsync(jobMonRequest);
if (jobMonResponse == null)
return null;
if (jobMonResponse.jobrun.Length > 1)
throw new Exception("More than one job found, Wizards are abound.");
return jobMonResponse.jobrun.Single().id;
}
How to implement interface method that returns TaskT?
When you have to implement an async method from an interface and your implementation is synchronous, you can either use Ned's solution:
public Task<Bar> CreateBarAsync()
{
return Task.FromResult<Bar>(SynchronousBarCreator());
}
With this solution, the method looks async but is synchronous.
Or the solution you proposed:
Task<Bar> CreateBarAsync()
{
return Task.Run(() => SynchronousBarCreator());
}
This way the method is truly async.
You don't have a generic solution that will match all cases of "How to implement interface method that returns Task". It depends on the context: is your implementation fast enough so invoking it on another thread is useless? How is this interface used a when is this method invoked (will it freeze the app)? Is it even possible to invoke your implementation in another thread?
How do you handle a 3rd party interface returning Task if you don't have any async code?
If you don't have async work to do don't include the async
keyword. Your GetValueAsnyc
function was almost correct, you just needed to drop the async
. For your DoWorkAsync
you should just not mark the method async and return a completed task.
public class FooBar : IFoo
{
public Task DoWorkAsync()
{
// Do Some Work
//If you can use .NET 4.6
return Task.CompletedTask;
//For older versions, the thing you pass in does not matter, I like to use bool.
return Task.FromResult(false);
}
public Task<int> GetValueAsync()
{
// Do Some Work
var result = ...;
return Task.FromResult(result);
}
}
However, if your code is slow and you end up blocking the UI for a long period of time I would consider looking in to if you can re-write your code as actually being async or perhaps wrapping the code in to a background thread, but I would only do a background thread if it was a last resort.
Implementing an interface that requires a Task return type in synchronous code
Yes: now there's Task.CompletedTask
as of .NET 4.6.
Is returning Task.FromResultvalue when doing synchronous work to satisfy interface bad?
Is this considered the right approach for situations like this?
I would say No, for rather subtle reasons.
Task.FromResult
allows you to return a task from a non-async
method, sure. And it works fine for the successful case. But it doesn't work as expected for the exceptional case.
Methods with an asynchronous signature are expected to place all the method results on the returned task. They can complete synchronously - there's nothing wrong with that - but any exception is considered a "result" in this sense and should be placed on the returned task.
So, you'd want to catch any exceptions from ExecuteSyncCode
(or even new TaskResult()
) and return Task.FromException
if there was one. And then to be properly pedantic, you may also want to catch OperationCanceledException
explicitly and return Task.FromCanceled
. By the time you're done handling all the corner cases, your code ends up looking something like this.
And by that time, your "simple" synchronous implementation is full of a bunch of boilerplate that muddles up the code and confuses future maintainers.
For this reason, I tend to prefer just marking the method as async
and not using await
. This will cause a compiler warning (CS1998 This async method lacks 'await' operators and will run synchronously.
), which is generally useful but which you can #pragma ignore
for this specific case since you want a synchronous implementation. Using async
essentially makes the compiler do all that boilerplate for you, while keeping the implementation synchronous.
If you end up with several synchronous implementations of asynchronous interfaces, I'd recommend defining a couple static helper methods like this. That way, the ugly #pragma
s are confined to a single helper class.
Interface Requiring Function That Returns Task
You could Return Task.CompletedTask
. This is useful in cases like the one you describe where you need to satisfy an interface method that returns a Task, but you have nothing to await in your concrete implementation.
Public Function MoveToNextField() As Task Implements FormObjects.Interfaces.IViewer.MoveToNextField
Return Task.CompletedTask
End Function
Related Topics
Password Encryption/Decryption Code in .Net
Static Property Using Inotifypropertychanged. C#
Accelerating Bitmap Grayscale Conversion, Is Openmp an Option in C#
How to Make an Installer for My C# Application
Convert an Object to an Xml String
Password Encryption/Decryption Code in .Net
ASP.NET MVC - Passing Parameters to the Controller
Owin's Getexternallogininfoasync Always Returns Null
Wpf Error 40 Bindingexpression Path Error: Property Not Found on 'Object'
Azure Shared Access Signature - Signature Did Not Match
Basic Simple ASP.NET + Jquery + JSON Example
How to Hide Wpf Datagrid Columns Depending on a Property
Moving Mouse Cursor Programmatically
Merge Multiple Word Documents into One Open Xml
Main: Not All Code Paths Return a Value
Change the Value in App.Config File Dynamically