I have an interface, which delivers me a certain path. In one of my implementations I need to use async, but I haven't figured out how to get the result of an async method into a synchronous method. Here is the code sample:
Interface:
public interface IFilePath
{
string GetAsset();
}
Problematic implementation:
public class FilePath : IFilePath
{
public string GetAsset()
{
return GetAssetAssync();
}
private async Task<string> GetAssetAssync()
{
StorageFolder assetsFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync(#"Assets").AsTask().ConfigureAwait(false);
return assetsFolder.Path;
}
}
Only for this implementation I need the async call. All others do not need it. So I can't use public Task<string> GetAsset() or can I somehow?
A Task-returning method indicates that the implementation may be asynchronous. So, the best approach is to update your interface to allow asynchronous implementations:
public interface IFilePath
{
Task<string> GetAssetAsync();
}
I would attempt to make the other implementations asynchronous (file I/O is a naturally asynchronous operation), but if you have truly synchronous implementations (e.g., reading from an in-memory zip file or something), then you can wrap your result in Task.FromResult:
class SynchronousFilePath: IFilePath
{
public string GetAsset(); // natural synchronous implementation
public Task<string> GetAssetAsync()
{
return Task.FromResult(GetAsset());
}
}
Related
My Xamarin.Forms app has several interfaces (for Dependencys) with implementations for Android and iOS. The methods in them are not async. Now I want to add the implementations for these interfaces for UWP, but several of the needed methods are async so they don't fit the signatures. How do I deal with this? Is the only solution to create a separate interface for UWP?
In these scenarios I tend to use the Task.FromResult method for the non-async implementations. Example: you have a method on Windows that returns a Task of type bool and you want to implement the same functionality on Android and iOS for methods that return bool.
public interface ISample
{
public Task<bool> GetABool();
}
On Windows you would just return the Task
public class WindowsSample : ISample
{
public Task<bool> GetABool()
{
// whatever implementation
return SomeTaskOfTypeBool();
}
}
On Android or iOS you would wrap the value in a Task
public class AndroidSample : ISample
{
public Task<bool> GetABool()
{
// replace with however you get the value.
var ret = true;
return Task.FromResult(ret);
}
}
You can not use the await keyword. You have to create a new Task and wait for the Task to finish. A separate interface is not necessary. Exception handling with Tasks can be tricky, inform yourself.
Calling an async method Method1 with return value:
string s = Task.Run(() => Method1()).Result;
Without return value:
Task.Run(() => Method1()).Wait;
.Rest or .Wait block until the Task is completed.
More Details:
Calling async methods from non-async code
I have the interface:
public interface IService
{
Task<double> GetData(int id);
}
And I need to use this interface in my class:
//_svc is a Type of IService
public async void Doit()
{
Task<double> task = await _svc.GetData(id);
}
And when I do it, it says that it can't convert type double into Task<double>
Why is this double instead of the task? The interface clearly specifies that this is a task and here I need to get the task, not the value.
If you need the task to handle it yourself, then remove the await that handles it for you.
It is not an answer, but i hope it will help you to understand Tasks a little bit more. For example you have interface with method:
System.Threading.Tasks.Task<string> FindNameAsync(string computerName);
When you call a method from interface, it will be something like this:
var result = await _scv.FindNameAsync(name); //The program will not go to next line, until it becomes result
When it will get result it will go further. And result you can pass to next methods
EDIT
If you want to get statuses you can make little modifications:
System.Threading.Tasks.Task<bool> FindNameAsync(string computerName);
Then you can return true in case of success, in other case - false.
With a little modification you can pass object to method as parameter and save values that you need in it. Or you can return dictionary or turple, and not bool. Little example:
Your method can be like here:
System.Threading.Tasks.Task<bool> FindNameAsync(SomeClass obj);
And you can handle it so:
SomeClass test = new SomeClass();
if(await _scv.FindNameAsync(test))
{
//code for success result
}else
{
//if error happened handle here
}
The interface clearly specifies that this is a task and here I need to get the task, not the value.
When an interface declares a method that returns a Task or Task<T> the name of the method should - by convention - also end with "Async": https://msdn.microsoft.com/en-us/library/hh191443
Such a method is expected to be implemented as an async method that returns an object of type T if the return type is declared as Task<T> or nothing at all if the return type is just Task:
public interface IService
{
Task<double> GetDataAsync(int id);
}
public class Service : IService
{
public async Task<double> GetDataAsync(int id)
{
await Task.Delay(1000);
return 1.0;
}
}
You would await such a method:
public class Consumer
{
public async void Doit()
{
IService service = new Service();
double d = await service.GetDataAsync(1);
}
}
Now whether the method actually is implemented as an async method is an implementation detail in the concrete implementation of the interface but it doesn't really matter as far as the consumer of the interface is concerned as you can still always await a method that returns Task or Task (provided that the caller method is marked with the async keyword of course).
You would for example be able to await the following non-async implementation of the method the same way:
public class Service : IService
{
public Task<double> GetDataAsync(int id)
{
return Task.FromResult(1.0);
}
}
So methods that have a return type of Task or Task<T> are meant to be asynchronous and awaited.
You could still store an instance of the method's actual return type in a variable "as usual" though:
public void Doit()
{
IService service = new Service();
Task<double> task = service.GetDataAsync(1);
}
This would however simply call the asynchronous without waiting for its return value which makes it pretty useless to even call the method in the first place. When calling a - by contract and convention asynchronous - method that returns a Task<double> you are interested in getting the double value back asynchronously. You don't really care about the Task object itself if you understand what I mean.
This question already has answers here:
How to implement interface method that returns Task<T>?
(4 answers)
Closed 6 years ago.
I am working with a third-party dll which exposes methods which return Task and Task<T>. I don't have any control over this assembly or the interface, and I assume the author assumed everything would need to be async since the naming of the methods are *Async() as shown below.
Given that, how do I properly implement the interface if I don't actually have any asynchronous code running?
public interface IFoo
{
Task DoWorkAsync();
Task<int> GetValueAsync();
}
My attempt was the following:
public class FooBar : IFoo
{
public async Task DoWorkAsync()
{
// Do Some Work
await Task.Yield();
}
public async Task<int> GetValueAsync()
{
// Do Some Work
var result = ...;
return Task.FromResult(result);
}
}
Additionally:
Was the author correct in exposing only methods that returned Task/Task<T>?
Was the author correct in suffixing method names with *Async()? Code analysis doesn't complain if I write an async method without appending Async to the name.
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.
I have an application with a factory service to allow construction of instances while resolving the necessary dependency injection. For instance, I use this to construct dialog view models. I have a service interface that looks like this:
public interface IAsyncFactory
{
Task<T> Build<T>() where T: class, IAsyncInitialize;
}
Ideally, what I'd like to have is something like this (pseudo-syntax, as this isn't directly achievable)
public interface IFactory
{
Task<T> Build<T>() where T: class, IAsyncInitialize;
T Build<T>() where T: class, !IAsyncInitialize;
}
The idea here is that if a class supports IAsyncInitialize, I'd like the compiler to resolve to the method that returns Task<T> so that it's obvious from the consuming code that it needs to wait for initialization. If the class does not support IAsyncInitialize, I'd like to return the class directly. The C# syntax doesn't allow this, but is there a different way to achieve what I'm after? The main goal here is to help remind the consumer of the class of the correct way to instantiate it, so that for classes with an asynchronous initialization component, I don't try to use it before it has been initialized.
The closest I can think of is to create separate Build and BuildAsync methods, with a runtime error if you call Build for an IAsyncInitialize type, but this doesn't have the benefit of catching errors at compile time.
In general Microsoft suggests to add async suffix when naming asynchronous methods. Thus, your assumption of creating two methods named as Build and BuildAsync makes sense.
I think there is no way to enforce something like "all types that do not implement IAsyncInitialize shall use Build method instead of BuildAsync" unless you force the developers to mark synchronous methods with another interface like ISynchronousInitialize.
You may try the following;
instead of having to separate methods, just implement one BuildAsync method which has the following signature:
Task<T> BuildAsync<T>() where T: class
In the BuildAsync method check whether T implements IAsyncInitialize. If this is the case, just call related initialization code after creating the object of type T. Otherwise, just create a TaskCompletionSource object and run the synchronous initialization code as if it is asynchronous.
The following approach might not be the best, but I find it very convenient. When both asynchronous and synchronous initializers are available (or possibly can be available), I wrap the synchronous one as asynchronous with Task.FromResult, and only expose the asynchronous method to the client:
public interface IAsyncInitialize
{
Task InitAsync();
int Data { get; }
}
// sync version
class SyncClass : IAsyncInitialize
{
readonly int _data = 1;
public Task InitAsync()
{
return Task.FromResult(true);
}
public int Data { get { return _data; } }
}
// async version
class AsyncClass: IAsyncInitialize
{
int? _data;
public async Task InitAsync()
{
await Task.Delay(1000);
_data = 1;
}
public int Data
{
get
{
if (!_data.HasValue)
throw new ApplicationException("Data uninitalized.");
return _data.Value;
}
}
}
This leaves only the asynchronous version of the factory:
public interface IAsyncFactory
{
// Build can create either SyncClass or AsyncClass
Task<T> Build<T>() where T: class, IAsyncInitialize;
}
Furthermore, I prefer to avoid dedicated initializer methods like InitAsync, and rather expose asynchronous properties directly as tasks:
public interface IAsyncData
{
Task<int> AsyncData { get; }
}
// sync version
class SyncClass : IAsyncData
{
readonly Task<int> _data = Task.FromResult(1);
public Task<int> AsyncData
{
get { return _data; }
}
}
// async versions
class AsyncClass : IAsyncData
{
readonly Task<int> _data = GetDataAsync();
public Task<int> AsyncData
{
get { return _data; }
}
private static async Task<int> GetDataAsync()
{
await Task.Delay(1000);
return 1;
}
}
In either case, it always imposes asynchrony on the client code, i.e.:
var sum = await provider1.AsyncData + await provider2.AsyncData;
However, I don't think it's an issue as the overhead of Task.FromResult and await Task.FromResult for the synchronous version is quite low. I'm going to post some benchmarks.
The approach using asynchronous properties can be further improved with Lazy<T>, e.g. like this:
public class AsyncData<T>
{
readonly Lazy<Task<T>> _data;
// expose async initializer
public AsyncData(Func<Task<T>> asyncInit, bool makeThreadSafe = true)
{
_data = new Lazy<Task<T>>(asyncInit, makeThreadSafe);
}
// expose sync initializer as async
public AsyncData(Func<T> syncInit, bool makeThreadSafe = true)
{
_data = new Lazy<Task<T>>(() =>
Task.FromResult(syncInit()), makeThreadSafe);
}
public Task<T> AsyncValue
{
get { return _data.Value; }
}
}
Trying to understand the new async/await pattern, I have one question which I can't find an answer to, namely if I should decorate my methods with async, if I intend to call those methods from other async functions, or just return Tasks where appropriate?
In other words, which of these classes A, B or C is best, and why?
class A<T>
{
public async Task<T> foo1() //Should be consumed
{
return await foo2();
}
public async Task<T> foo2() //Could be consumed
{
return await foo3();
}
private async Task<T> foo3() //Private
{
return await Task.Run(...);
}
}
class B<T>
{
public async Task<T> foo1() //Should be consumed
{
return await foo2();
}
public async Task<T> foo2() //Could be consumed
{
return await foo3();
}
private Task<T> foo3() //Private
{
return Task.Run(...);
}
}
class C<T>
{
public async Task<T> foo1() //Should be consumed
{
return await foo2();
}
public Task<T> foo2() //Could be consumed
{
return foo3();
}
private Task<T> foo3() //Private
{
return Task.Run(...);
}
}
It seems redundant to overdecorate methods so I naturally lean toward C, but at the same time it feels somewhat awkward to work with Task<T> unless you use the await keyword.
Both versions work effectively the same, the only difference is that when you use await here, you get some performance penalty (because the state machine must be set up and a continuation will most likely be used).
So, it comes down to a tradeoff: Do you want your methods to be somewhat more efficient at the cost of being slightly less readable? Or are you willing to sacrifice performance for readability?
Usually, I would advise you to go for readability first and only focus on performance if profiling tells you it's worth it. But in this case, I think the increase in readability is small, so I would probably not use await.
Also note that your class C still doesn't go far enough: foo1() also doesn't need await.
The async in the signature is there to allow the compiler to create the state-machine rewriting of the contained code that is necessary to implement the await semantics in the general case.
Your example is exactly the special case where you do not need that rewriting: The asynchronous operation is the last thing happening within a method. That kind of method is already possible and valid in .NET4.0. This compatibility might be one reason to avoid async when you do not need it.