Kick off async method in constructor in c# - c#

I'm wondering is it safe to call async method in a constructor in the following way:
Let's say we have an async method Refresh that is fetching data from the internet. We are also using Reactive Extensions to notify everyone that is interested that new data was fetched.
I'm wondering is it safe to call Refresh first time in a class constructor? Can I use such construction?
Task.Run(Refresh);
or
Refresh().ConfigureAwait(false)
I'm not really interested here if the method has finished or not, since I will get notified through Reactive Extensions when data is fetched.
Is it ok to do something like this?
public class MyClass
{
BehvaiorSubject<Data> _dataObservable = new BehvaiorSubject(Data.Default);
IObservable DataObservable => _dataObservable;
public MyClass()
{
Refresh().ConfigureAwait(false);
}
public async Task Refresh()
{
try
{
var data = await FetchDataFromNetwork();
_dataObservable.OnNext(data);
}
catch (VariousExceptions e)
{
//do some appropriate stuff
}
catch(Exception)
{
//do some appropriate stuff
}
}
}

Though people are against the idea, we have similar things in our project :)
The thing is you have to properly handle any exceptions thrown from that Task in case they go unobserved. Also you might need to expose the task via either a method or a property, just so that it is possible to await (when necessary) the async part is finished.
class MyClass
{
public MyClass()
{
InitTask = Task.Delay(3000);
// Handle task exception.
InitTask.ContinueWith(task => task.Exception, TaskContinuationOptions.OnlyOnFaulted);
}
public Task InitTask { get; }
}

Related

Force C# async tasks to be lazy?

I have a situation where I have an object tree created by a special factory. This is somewhat similar to a DI container, but not quite.
Creation of objects always happens via constructor, and the objects are immutable.
Some parts of the object tree may not be needed in a given execution and should be created lazily. So the constructor argument should be something that is just a factory for on-demand creation. This looks like a job for Lazy.
However, object creation may need to access slow resources and is thus always async. (The object factory's creation function returns a Task.) This means that the creation function for the Lazy would need to be async, and thus the injected type needs to be Lazy<Task<Foo>>.
But I'd rather not have the double wrapping. I wonder if it is possible to force a Task to be lazy, i.e. to create a Task that is guaranteed to not execute until it is awaited. As I understand it, a Task.Run or Task.Factory.StartNew may start executing at any time (e.g. if a thread from the pool is idle), even if nothing is waiting for it.
public class SomePart
{
// Factory should create OtherPart immediately, but SlowPart
// creation should not run until and unless someone actually
// awaits the task.
public SomePart(OtherPart eagerPart, Task<SlowPart> lazyPart)
{
EagerPart = eagerPart;
LazyPart = lazyPart;
}
public OtherPart EagerPart {get;}
public Task<SlowPart> LazyPart {get;}
}
I'm not sure exactly why you want to avoid using Lazy<Task<>>,, but if it's just for keeping the API easier to use, as this is a property, you could do it with a backing field:
public class SomePart
{
private readonly Lazy<Task<SlowPart>> _lazyPart;
public SomePart(OtherPart eagerPart, Func<Task<SlowPart>> lazyPartFactory)
{
_lazyPart = new Lazy<Task<SlowPart>>(lazyPartFactory);
EagerPart = eagerPart;
}
OtherPart EagerPart { get; }
Task<SlowPart> LazyPart => _lazyPart.Value;
}
That way, the usage is as if it were just a task, but the initialisation is lazy and will only incur the work if needed.
#Max' answer is good but I'd like to add the version which is built on top of Stephen Toub' article mentioned in comments:
public class SomePart: Lazy<Task<SlowPart>>
{
public SomePart(OtherPart eagerPart, Func<Task<SlowPart>> lazyPartFactory)
: base(() => Task.Run(lazyPartFactory))
{
EagerPart = eagerPart;
}
public OtherPart EagerPart { get; }
public TaskAwaiter<SlowPart> GetAwaiter() => Value.GetAwaiter();
}
SomePart's explicitly inherited from Lazy<Task<>> so it's clear that it's lazy and asyncronous.
Calling base constructor wraps lazyPartFactory to Task.Run to avoid long block if that factory needs some cpu-heavy work before real async part. If it's not your case, just change it to base(lazyPartFactory)
SlowPart is accessible through TaskAwaiter. So SomePart' public interface is:
var eagerValue = somePart.EagerPart;
var slowValue = await somePart;
Declaration:
private Lazy<Task<ServerResult>> _lazyServerResult;`
ctor()
{
_lazyServerResult = new Lazy<Task<ServerResult>>(async () => await
GetServerResultAsync())
}
Usage:
ServerResult result = await _lazyServerResult.Value;
Using the constructor for Task make the task lazy a.k.a not running until you say it to run, so you could do something like this:
public class TestLazyTask
{
private Task<int> lazyPart;
public TestLazyTask(Task<int> lazyPart)
{
this.lazyPart = lazyPart;
}
public Task<int> LazyPart
{
get
{
// You have to start it manually at some point, this is the naive way to do it
this.lazyPart.Start();
return this.lazyPart;
}
}
}
public static async void Test()
{
Trace.TraceInformation("Creating task");
var lazyTask = new Task<int>(() =>
{
Trace.TraceInformation("Task run");
return 0;
});
var taskWrapper = new TestLazyTask(lazyTask);
Trace.TraceInformation("Calling await on task");
await taskWrapper.LazyPart;
}
Result:
SandBox.exe Information: 0 : Creating task
SandBox.exe Information: 0 : Calling await on task
SandBox.exe Information: 0 : Task run
However I strongly recommend you to use Rx.NET and IObservable as in your case you will get way less troubles for handling less naive cases to start your task at the right moment.
Also it makes the code a bit cleaner in my opinion
public class TestLazyObservable
{
public TestLazyObservable(IObservable<int> lazyPart)
{
this.LazyPart = lazyPart;
}
public IObservable<int> LazyPart { get; }
}
public static async void TestObservable()
{
Trace.TraceInformation("Creating observable");
// From async to demonstrate the Task compatibility of observables
var lazyTask = Observable.FromAsync(() => Task.Run(() =>
{
Trace.TraceInformation("Observable run");
return 0;
}));
var taskWrapper = new TestLazyObservable(lazyTask);
Trace.TraceInformation("Calling await on observable");
await taskWrapper.LazyPart;
}
Result:
SandBox.exe Information: 0 : Creating observable
SandBox.exe Information: 0 : Calling await on observable
SandBox.exe Information: 0 : Observable run
To be more clear: The Observable here handle when to start the task, it is Lazy by default and will run the task everytime it is subscribed (here subscribe is used by the awaiter that enable the use of the await keyword).
You could, if you need to, make the task run only once every minute (or ever) and having its result published across all subscribers to save performance for instance, like in a real world app, all of this and many more is handled by observables.

MVVM c# how to load async data into a property?

I wonder if there's a better approach to load async data into a property. now I create an async function and raise a Task in the Get part of the property like this:
private ObservableCollection<CProyecto> prope;
public ObservableCollection<CProyecto> Prope
{
get
{
if (prope == null)
{
Task.Run(()=> LoadData()).Wait();
}
return proyectos;
}
set
{
prope = value;
RaisePropertyChanged();
}
}
async private Task LoadData()
{
Prope = await clsStaticClassDataLoader.GetDataFromWebService();
}
This approach works, but I don't like the use of .Wait, because that can freeze the screen if the service doesn´t respond fast.
Can you please guide me on this matter?
thanks in advance
The way I handled this was to start the process of loading the property when the object was constructed, but I did not await the result. Since the property notifies when it is populated, the bindings worked just fine. Essentially it works like this:
public class MyClass : INotifyPropertyChanged
{
private ObservableCollection<CProyecto> prope;
public ObservableCollection<CProyecto> Prope
{
get { return prope; }
set { prope = value; RaisePropertyChanged(nameof(Prope)); }
}
public MyClass()
{
// Don't wait or await. When it's ready
// the UI will get notified.
LoadData();
}
async private Task LoadData()
{
Prope = await clsStaticClassDataLoader.GetDataFromWebService();
}
}
This works very well, and does not cause any delays or stuttering in the UI. If you want the collection to never be null (a good practice IMO), you can pre-initialize the prope field with an empty collection.
I suggest you read my MSDN article on async MVVM data-binding. I have a library (github link) that provides a NotifyTask<T> type, which can be used as such:
public class MyClass : INotifyPropertyChanged
{
public NotifyTask<ObservableCollection<CProyecto>> Prope { get; private set; }
public MyClass()
{
// Synchronously *start* the operation.
Prope = NotifyTask.Create(LoadDataAsync());
}
async private Task<ObservableCollection<CProyecto>> LoadDataAsync()
{
return await clsStaticClassDataLoader.GetDataFromWebService();
}
}
Then your databinding would operate on Prope.Result.
The advantage of this approach is that you can also use databinding to hide/show busy indicators (Prope.IsNotCompleted), show controls when the data is available (Prope.IsSuccessfullyCompleted), and error notifications (Prope.IsFaulted / Prope.ErrorMessage).
Also, you can specify a non-null default value, if you wish:
Prope = NotifyTask.Create(LoadDataAsync(), new ObservableCollection<CProyecto>());
Your current implementation of the Prope property doesn't make much sense. It is pointless to execute the LoadData method on a background thread since you block the main thread anyway when you call Wait(). You might as well call Wait() directly on the task returned by the LoadData() method:
//BAD IMPLEMENTATION!
private ObservableCollection<CProyecto> prope;
public ObservableCollection<CProyecto> Prope
{
get
{
if (prope == null)
LoadData().Wait();
return proyectos;
}
set { prope = value; RaisePropertyChanged(); }
}
The above implementation is still a bad one. The getter of a property is not supposed to perform an asynchronous operation. You should read #Stephen Cleary's blog post on the subject: https://blog.stephencleary.com/2013/01/async-oop-3-properties.html
...and look into his NotifyTaskCompletion type in his AsyncEx library: https://github.com/StephenCleary/AsyncEx

How to implement async INotifyPropertyChanged

I have a class with properties that are bound to my view. To keep my view up-to-date, I implement INotifyPropertyChanged and raise the event everytime some property changes.
Now I got some heavy functions that freeze my application. I want to put them into a background task.
First: here my current approach
(e.g. on button click)
private async void HeavyFunc()
{
foreach (var stuff)
{
count += await Task.Run(() => stuff.Fetch());
}
if (count == 0)
//...
}
stuff class
public async Task<int> Fetch()
{
//network stuff
RaisePropertyChanged("MyProperty");
}
public async void RaisePropertyChanged(string pChangedProperty)
{
await Application.Current.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
new ThreadStart(() =>
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(pChangedProperty);
}
);
}
The code above gives an exception ("DependencySource" must be created in the same thread like "DependencyObject").
AFAIK, you generally need to create a new thread and run it (while awaiting it). ´await Task.Run(...);´ should do this job.
Since the PropertyChanged event directly influences the UI, calling it in the UI thread seems to be a good decision. This is why I call Dispatcher.BeginInvoke.
What I don't understand: the exception above is caused when different threads are responsible for the data. But I explicitely calling the event on my UI-thread and the object should be created by the UI-thread too. So why do I get an exception?
My main question is: How do I implement the events for the INotifyPropertyChanged interface generally to avoid or handle most of the async programming problems like above? What should be considered while constructing the functions?
Now I got some heavy functions that freeze my application.
If you're really doing asynchronous "network stuff", then it shouldn't be freezing the app.
My main question is: How do I implement the events for the INotifyPropertyChanged interface generally to avoid or handle most of the async programming problems like above?
The approach that I prefer is to not handle this in the event raising code. Instead, structure the rest of your code so that it respects the UI layer.
In other words, divide your "service" (or "business logic") code from your "UI" code so that it works like this:
// In StuffService class:
public async Task<Result> FetchAsync()
{
//network stuff
return result;
}
// In StuffViewModel class:
public async void ButtonClicked()
{
foreach (var stuff)
{
var result = await Task.Run(() => _stuffService.FetchAsync());
MyProperty = result.MyProperty;
count += result.Count;
}
if (count == 0)
//...
}
public Property MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
RaisePropertyChanged();
}
}
private void RaisePropertyChanged([CallerMemberName] string pChangedProperty = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(pChangedProperty));
}
This way, there's no manual thread jumping, all properties have the standard ViewModel implementation, the code is simpler and more maintainable, etc.
I did leave in the call to Task.Run, although this should be superfluous if your network calls are truly asynchronous.

How to create an awaitable class? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can constructors be async
I have a class Example that pulls several information from the internet on creation.
public class Example
{
string information;
public Example()
{
//Pull information
}
}
Now I would like to let Example become awaitable because it is important that Example is created before continuing the part after creation.
public async void SetupSomething()
{
Example ex = new Example();
await ex;
// Do something with ex
}
How can I do this?
You could do that, but I think that's not a good approach, because there is nothing forcing the await before you start using the instance.
I think a good idea would be to create static asynchronous method that creates your object. Something like:
class Example
{
private Example()
{
}
private async Task InitializeAsync()
{
// get the required data asynchronously here
}
public static async Task<Example> CreateAsync()
{
var result = new Example();
await result.InitializeAsync();
return resul;
}
}
Well, the constructor should wait until it is done doing it's stuff. After all, the thread use to create it is from the method that calls it.
However, what I think would be very important, is to show us what that constructor is doing. There's a good chance it is calling something somewhere that start another thread and doesn't wait for it to resolve, making the constructor returns while not having all the "information" you are talking about.
Might be similar to: C# : Blocking a function call until condition met

Is there a common pattern for initializing object on a background thread?

I have an object that takes a long time to be initialized. Therefore I the capability to Start Initializing on application startup. Any subsequent calls to methods on the class we need to have a delay mechanism that waits for the class to finish initialization.
I have a couple of potential solutions however I am not entirely satisfied with either of them. The first uses Task.Delay in a while loop and the second uses SemaphoreSlim but involves some unnecessary blocking. I feel this must be a fairly common requirement, can anybody provide some advice on how to best manage this?
Oh btw, this is a Metro application so we have limited API's
Here is the pseudocode:
public class ExposeSomeInterestingItems
{
private InitialisationState _initialised;
private readonly SemaphoreSlim _waiter =
new SemaphoreSlim(0);
public async Task StartInitialize()
{
if (_initialised == InitialisationState.Initialised)
{
throw new InvalidOperationException(
"Attempted to initialise ActiveTrackDown" +
"loads when it is already initialized");
}
_initialised =
InitialisationState.StartedInitialisation;
new TaskFactory().StartNew(async () =>
{
// This takes some time to load
this._interestingItems =
InterestingItemsLoader.LoadItems();
_waiter.Release();
_initialised = InitialisationState.Initialised;
});
}
public InterestingItem GetItem(string id)
{
DelayUntilLoaded();
DelayUntilLoadedAlternative();
}
private async Task DelayUntilLoaded()
{
if (_initialised == InitialisationState.NotInitialised)
{
throw new InvalidOperationException("Error " +
"occurred attempting to access details on " +
"ActiveTrackDownloads before calling initialise");
}
while (true)
{
if (_initialised == InitialisationState.Initialised)
{
return;
}
await Task.Delay(300);
}
}
private async Task DelayUntilLoadedAlternative()
{
if (_initialised == InitialisationState.NotInitialised)
{
throw new InvalidOperationException(
"Error occurred attempting to access details " +
"on ActiveTrackDownloads before calling initialise");
}
try
{
await _waiter.WaitAsync();
}
finally
{
_waiter.Release();
}
}
}
I think that a better design would be an asynchronous factory, where the calling code awaits the object creation and then receives a regular object instance.
Stealing liberally from Stephen Toub:
public class AsyncLazy<T> : Lazy<Task<T>>
{
public AsyncLazy(Func<T> valueFactory) :
base(() => Task.Run(valueFactory)) { }
public AsyncLazy(Func<Task<T>> taskFactory) :
base(() => Task.Run(taskFactory)) { }
public TaskAwaiter<T> GetAwaiter() { return Value.GetAwaiter(); }
}
public static class ExposeSomeInterestingItemsFactory
{
public static AsyncLazy<ExposeSomeInterestingItems> Instance
{
get { return _instance; }
}
private static readonly AsyncLazy<ExposeSomeInterestingItems> _instance =
new AsyncLazy<ExposeSomeInterestingItems>(() => new ExposeSomeInterestingItems());
public static void StartInitialization()
{
var unused = Instance.Value;
}
}
public class ExposeSomeInterestingItems
{
public ExposeSomeInterestingItems()
{
// This takes some time to load
this._interestingItems = InterestingItemsLoader.LoadItems();
}
public InterestingItem GetItem(string id)
{
// Regular logic. No "delays".
}
}
...
var exposeSomeInterestingItems = await ExposeSomeInterestingItemsFactory.Instance;
var item = exposeSomeInterestingItems.GetItem("id");
That way, you keep the Single Responsibility Principle nicely:
AsyncLazy<T> combines Task<T> with Lazy<T> (so the instance is created asynchronously only when needed).
ExposeSomeInterestingItemsFactory contains construction logic.
ExposeSomeInterestingItems is only concerned with exposing interesting items, rather than having to pollute all its members with asynchronous delays.
Also, this solution is asynchronous throughout (no blocking), which is good (particularly for Metro apps).
Update, 2012-09-14: I've taken this code and cleaned it up and commented it on my blog.
You can use the Task<T> for this. This will take care of all the synchronisation for you and allows you to block untill the value is available:
private static Task<HeavyObject> heavyObjectInitializer;
// Call this method during application initialization
public static void Bootstrap()
{
heavyObjectInitializer = new Task<HeavyObject>(() =>
{
// creation of heavy object here
return new HeavyObject();
});
// Start running the initialization right now on a
// background thread. We don't have to wait on this.
heavyObjectInitializer.Start();
}
// Call this method whenever you need to use the object.
public static HeavyObject GetHeavyObject()
{
// Get the initialized object, or block untill this
// instance gets available.
return heavyObjectInitializer.Result;
}
Optionally, you can also query to see if the object is available or not:
public static bool IsHeavyObjectAvailable
{
get { return heavyObjectInitializer.IsCompleted; }
}
Put the method calls into a queue which you process when you finish initialising. Only put methods into the queue when you have not yet initialised.
You could move to a an event driven architecture where you application is in different states.
Initially the application moves into the Starting state. In this state HeavyObject is created using a background task. When the initialization is complete an event is fired. (You don't have to use an actual .NET event. You can use callbacks or something similar and frameworks like Reactive Extensions allows you to compose sequences of events.)
When all initialization events have fired you move into the Started state of your application. For an UI application this could modify the UI to enable some previously disabled operations.
Check this Prototype Pattern. Maybe it can help you
You only need to create your object once and clone it when you need another one.

Categories