Multiple Asynchronous Task execution - c#

Please bear with me :-)
I'm struggling with the TPL in c# and am stuck trying to figure out the best way to design a solution for kicking off multiple async tasks, waiting for them to complete, and moving on. My initial POC is below. Each IDataGatherer instance needs to get the data and massage it into a DataObject instance.
I'm unsure of how to handle the continuation from the DownloadStringTaskAsync call such that I can take the result and massage it into a DataObject. ContinueWith wants to be provided a method with void return signature but I feel like the ExtractData method needs to return a Task instance or else I don't have a Task instance to return from the GetDataAsync() method.
I'm also wondering if I need to introduce a TaskCompletionSource in my IDataGatherer instances but how do I hitch that onto the task(s) that are doing the real work - DownloadstringTaskAsync and ExtractData for example?
interface IDataGatherer
{
Task<DataObject> GetDataAsync();
}
class DataObject
{
public string Data { get; set; }
}
class IpGatherer : IDataGatherer
{
private readonly string _url = "http://ip.jsontest.com";
public Task<DataObject> GetDataAsync()
{
var tcs = new TaskCompletionSource<DataObject>(); // Do I need this???
var client = new WebClient();
// stuck here
var task = client.DownloadStringTaskAsync(_url).ContinueWith(ExtractData);
}
private void ExtractData(Task<string> obj)
{
}
}
class Program
{
private static void Main(string[] args)
{
// takes a list of IDataGatherers and waits for them
// all to complete, handles exceptions, etc.
}
}
Designing the solution this way may be over-complicating things so I'm open to suggestions to clean things up or do them more succinctly.
I'm using .NET 4.5

First, you don't need TaskCompletionSource. That's because ContinueWith() can be provided with a method with non-void signature. E.g.:
public Task<DataObject> GetDataAsync()
{
var client = new WebClient();
return client.DownloadStringTaskAsync(_url)
.ContinueWith((Func<Task<string>, DataObject>)ExtractData);
}
private DataObject ExtractData(Task<string> task)
{
return new DataObject(task.Result);
}
(Using Result won't block, because you can be certain the Task will be completed at that point.)
But since you're using DownloadStringTaskAsync(), you're likely on .Net 4.5, which means you can use await. That makes the code even simpler:
public async Task<DataObject> GetDataAsync()
{
var client = new WebClient();
var s = await client.DownloadStringTaskAsync(_url);
return ExtractData(s);
}
private DataObject ExtractData(string s)
{
return new DataObject(s);
}

Related

Kick off async method in constructor in 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; }
}

Do I need Task.Run to call an async method from a constructor? [duplicate]

I have a project where I'm trying to populate some data in a constructor:
public class ViewModel
{
public ObservableCollection<TData> Data { get; set; }
async public ViewModel()
{
Data = await GetDataTask();
}
public Task<ObservableCollection<TData>> GetDataTask()
{
Task<ObservableCollection<TData>> task;
//Create a task which represents getting the data
return task;
}
}
Unfortunately, I'm getting an error:
The modifier async is not valid for this item
Of course, if I wrap in a standard method and call that from the constructor:
public async void Foo()
{
Data = await GetDataTask();
}
it works fine. Likewise, if I use the old inside-out way
GetData().ContinueWith(t => Data = t.Result);
That works too. I was just wondering why we can't call await from within a constructor directly. There are probably lots of (even obvious) edge cases and reasons against it, I just can't think of any. I've also search around for an explanation, but can't seem to find any.
Since it is not possible to make an async constructor, I use a static async method that returns a class instance created by a private constructor. This is not elegant but it works ok.
public class ViewModel
{
public ObservableCollection<TData> Data { get; set; }
//static async method that behave like a constructor
async public static Task<ViewModel> BuildViewModelAsync()
{
ObservableCollection<TData> tmpData = await GetDataTask();
return new ViewModel(tmpData);
}
// private constructor called by the async method
private ViewModel(ObservableCollection<TData> Data)
{
this.Data = Data;
}
}
Constructor acts very similarly to a method returning the constructed type. And async method can't return just any type, it has to be either “fire and forget” void, or Task.
If the constructor of type T actually returned Task<T>, that would be very confusing, I think.
If the async constructor behaved the same way as an async void method, that kind of breaks what constructor is meant to be. After constructor returns, you should get a fully initialized object. Not an object that will be actually properly initialized at some undefined point in the future. That is, if you're lucky and the async initialization doesn't fail.
All this is just a guess. But it seems to me that having the possibility of an async constructor brings more trouble than it's worth.
If you actually want the “fire and forget” semantics of async void methods (which should be avoided, if possible), you can easily encapsulate all the code in an async void method and call that from your constructor, as you mentioned in the question.
Your problem is comparable to the creation of a file object and opening the file. In fact there are a lot of classes where you have to perform two steps before you can actually use the object: create + Initialize (often called something similar to Open).
The advantage of this is that the constructor can be lightweight. If desired, you can change some properties before actually initializing the object. When all properties are set, the Initialize/Open function is called to prepare the object to be used. This Initialize function can be async.
The disadvantage is that you have to trust the user of your class that he will call Initialize() before he uses any other function of your class. In fact if you want to make your class full proof (fool proof?) you have to check in every function that the Initialize() has been called.
The pattern to make this easier is to declare the constructor private and make a public static function that will construct the object and call Initialize() before returning the constructed object. This way you'll know that everyone who has access to the object has used the Initialize function.
The example shows a class that mimics your desired async constructor
public MyClass
{
public static async Task<MyClass> CreateAsync(...)
{
MyClass x = new MyClass();
await x.InitializeAsync(...)
return x;
}
// make sure no one but the Create function can call the constructor:
private MyClass(){}
private async Task InitializeAsync(...)
{
// do the async things you wanted to do in your async constructor
}
public async Task<int> OtherFunctionAsync(int a, int b)
{
return await ... // return something useful
}
Usage will be as follows:
public async Task<int> SomethingAsync()
{
// Create and initialize a MyClass object
MyClass myObject = await MyClass.CreateAsync(...);
// use the created object:
return await myObject.OtherFunctionAsync(4, 7);
}
if you make constructor asynchronous, after creating an object, you may fall into problems like null values instead of instance objects. For instance;
MyClass instance = new MyClass();
instance.Foo(); // null exception here
That's why they don't allow this i guess.
In this particular case, a viewModel is required to launch the task and notify the view upon its completion. An "async property", not an "async constructor", is in order.
I just released AsyncMVVM, which solves exactly this problem (among others). Should you use it, your ViewModel would become:
public class ViewModel : AsyncBindableBase
{
public ObservableCollection<TData> Data
{
get { return Property.Get(GetDataAsync); }
}
private Task<ObservableCollection<TData>> GetDataAsync()
{
//Get the data asynchronously
}
}
Strangely enough, Silverlight is supported. :)
I was just wondering why we can't call await from within a constructor directly.
I believe the short answer is simply: Because the .Net team has not programmed this feature.
I believe with the right syntax this could be implemented and shouldn't be too confusing or error prone. I think Stephen Cleary's blog post and several other answers here have implicitly pointed out that there is no fundamental reason against it, and more than that - solved that lack with workarounds. The existence of these relatively simple workarounds is probably one of the reasons why this feature has not (yet) been implemented.
calling async in constructor maybe cause deadlock, please refer to
http://social.msdn.microsoft.com/Forums/en/winappswithcsharp/thread/0d24419e-36ad-4157-abb5-3d9e6c5dacf1
http://blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115163.aspx
Some of the answers involve creating a new public method. Without doing this, use the Lazy<T> class:
public class ViewModel
{
private Lazy<ObservableCollection<TData>> Data;
async public ViewModel()
{
Data = new Lazy<ObservableCollection<TData>>(GetDataTask);
}
public ObservableCollection<TData> GetDataTask()
{
Task<ObservableCollection<TData>> task;
//Create a task which represents getting the data
return task.GetAwaiter().GetResult();
}
}
To use Data, use Data.Value.
C# doesn't allow async constructors. Constructors are meant to return fast after some brief initialization. You don't expect and you don't want to wait for an instance i.e. the constructor to return. Therefore, even if async constructors were possible, a constructor is not a place for long-running operations or starting background threads. The only purpose of a constructor is initialization of instance or class members to a default value or the captured constructor parameters. You always create the instance and then call DoSomething() on this instance. Async operations are no exception. You always defer expensive initialization of members.
There are a few solutions to avoid the requirement of async constructors.
A simple alternative solution using Lazy<T> or AsyncLazy<T> (requires to install the Microsoft.VisualStudio.Threading package via the NuGet Package Manager). Lazy<T> allows to defer the instantiation or allocation of expensive resources.
public class OrderService
{
public List<object> Orders => this.OrdersInitializer.GetValue();
private AsyncLazy<List<object>> OrdersInitializer { get; }
public OrderService()
=> this.OrdersInitializer = new AsyncLazy<List<object>>(InitializeOrdersAsync, new JoinableTaskFactory(new JoinableTaskContext()));
private async Task<List<object>> InitializeOrdersAsync()
{
await Task.Delay(TimeSpan.FromSeconds(5));
return new List<object> { 1, 2, 3 };
}
}
public static void Main()
{
var orderService = new OrderService();
// Trigger async initialization
orderService.Orders.Add(4);
}
You can expose the data using a method instead of a property
public class OrderService
{
private List<object> Orders { get; set; }
public async Task<List<object>> GetOrdersAsync()
{
if (this.Orders == null)
{
await Task.Delay(TimeSpan.FromSeconds(5));
this.Orders = new List<object> { 1, 2, 3 };
}
return this.Orders;
}
}
public static async Task Main()
{
var orderService = new OrderService();
// Trigger async initialization
List<object> orders = await orderService.GetOrdersAsync();
}
Use an InitializeAsync method that must be called before using the instance
public class OrderService
{
private List<object> orders;
public List<object> Orders
{
get
{
if (!this.IsInitialized)
{
throw new InvalidOperationException();
}
return this.orders;
}
private set
{
this.orders = value;
}
}
public bool IsInitialized { get; private set; }
public async Task<List<object>> InitializeAsync()
{
if (this.IsInitialized)
{
return;
}
await Task.Delay(TimeSpan.FromSeconds(5));
this.Orders = new List<object> { 1, 2, 3 };
this.IsInitialized = true;
}
}
public static async Task Main()
{
var orderService = new OrderService();
// Trigger async initialization
await orderService.InitializeAsync();
}
Instantiate the instance by passing the expensive arguments to the constructor
public class OrderService
{
public List<object> Orders { get; }
public async Task<List<object>> OrderService(List<object> orders)
=> this.Orders = orders;
}
public static async Task Main()
{
List<object> orders = await GetOrdersAsync();
// Instantiate with the result of the async operation
var orderService = new OrderService(orders);
}
private static async Task<List<object>> GetOrdersAsync()
{
await Task.Delay(TimeSpan.FromSeconds(5));
return new List<object> { 1, 2, 3 };
}
Use a factory method and a private constructor
public class OrderService
{
public List<object> Orders { get; set; }
private OrderServiceBase()
=> this.Orders = new List<object>();
public static async Task<OrderService> CreateInstanceAsync()
{
var instance = new OrderService();
await Task.Delay(TimeSpan.FromSeconds(5));
instance.Orders = new List<object> { 1, 2, 3 };
return instance;
}
}
public static async Task Main()
{
// Trigger async initialization
OrderService orderService = await OrderService.CreateInstanceAsync();
}
you can use Action inside Constructor
public class ViewModel
{
public ObservableCollection<TData> Data { get; set; }
public ViewModel()
{
new Action(async () =>
{
Data = await GetDataTask();
}).Invoke();
}
public Task<ObservableCollection<TData>> GetDataTask()
{
Task<ObservableCollection<TData>> task;
//Create a task which represents getting the data
return task;
}
}
you can create a wrapper and inject a functor representing the constructor:
class AsyncConstruct<T>
where T: class
{
private readonly Task<T> m_construction;
private T m_constructed;
public AsyncConstruct(Func<T> createFunc)
{
m_constructed = null;
m_construction = Task.Run(()=>createFunc());
}
public T Get()
{
if(m_constructed == null)
{
m_constructed = m_construction.Result;
}
return m_constructed;
}
}
Please bump this language request:
https://github.com/dotnet/csharplang/discussions/419
The amount of boilerplate code everyone needs to write to have a fully initialized async object is crazy and completely opposite of the trend in C# (less boilerplate).
I would use something like this.
public class MyViewModel
{
public MyDataTable Data { get; set; }
public MyViewModel()
{
loadData(() => GetData());
}
private async void loadData(Func<DataTable> load)
{
try
{
MyDataTable = await Task.Run(load);
}
catch (Exception ex)
{
//log
}
}
private DataTable GetData()
{
DataTable data;
// get data and return
return data;
}
}
This is as close to I can get for constructors.
I use this easy trick.
public sealed partial class NamePage
{
private readonly Task _initializingTask;
public NamePage()
{
_initializingTask = Init();
}
private async Task Init()
{
/*
Initialization that you need with await/async stuff allowed
*/
}
}
I'm not familiar with the async keyword (is this specific to Silverlight or a new feature in the beta version of Visual Studio?), but I think I can give you an idea of why you can't do this.
If I do:
var o = new MyObject();
MessageBox(o.SomeProperty.ToString());
o may not be done initializing before the next line of code runs. An instantiation of your object cannot be assigned until your constructor is completed, and making the constructor asynchronous wouldn't change that so what would be the point? However, you could call an asynchronous method from your constructor and then your constructor could complete and you would get your instantiation while the async method is still doing whatever it needs to do to setup your object.

Using Task.Run() for hardware interfacing thread invocations

I need to invoke a method that meets the following criteria.
The method may run for hours.
The method may interface with hardware.
The method may request user input (parameter values, confirmation, etc). The request should block the method until input has been received.
I have a prototype implementation that fulfills this criteria using the following design.
Assume a Form exists and contains a Panel.
The IntegerInput class is a UserControl with a TextBox and a Button.
public partial class IntegerInput : UserControl
{
public TaskCompletionSource<int> InputVal = new TaskCompletionSource<int>(0);
public IntegerInput()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int val = 0;
Int32.TryParse(textBox1.Text, out val);
InputVal.SetResult(val);
}
}
The Form1UserInput class is instanced by Form1. The container is a Panel set by Form1 before being provided to the invoking class.
public interface IUserInput
{
Task<int> GetInteger();
}
public class Form1UserInput : IUserInput
{
public Control container;
private IntegerInput integerInput = new IntegerInput();
public IntegerInput IntegerInput { get { return integerInput; } }
public async Task<int> GetInteger()
{
container.Invoke(new Action(() =>
{
container.Controls.Clear();
container.Controls.Add(integerInput);
}));
await integerInput.InputVal.Task;
return integerInput.InputVal.Task.Result;
}
}
The Demo class contains the method I want to invoke.
public class Demo
{
public IUserInput ui;
public async void MethodToInvoke()
{
// Interface with hardware...
// Block waiting on input
int val = await ui.GetInteger();
// Interface with hardware some more...
}
public async void AnotherMethodToInvoke()
{
// Interface with hardware...
// Block waiting on multiple input
int val1 = await ui.getInteger();
int val2 = await ui.getInteger();
// Interface with hardware...
}
}
This is a rough outline of what the invoking class looks like. The call to Task.Run() is accurate for my prototype.
public class Invoker
{
public async Task RunTestAsync(IUserInput ui)
{
object DemoInstance = Activator.CreateInstance(typeof(Demo));
MethodInfo method = typeof(Demo).GetMethod("MethodToInvoke");
object[] args = null;
((IUserInput)DemoInstance).ui = ui;
var t = await Task.Run(() => method.Invoke(DemoInstance, args));
// Report completion information back to Form1
}
}
The Form1 controller class instances the Invoker and calls RunTestAsync passing in an instance of Form1UserInput.
I am aware of some concerns about long running Tasks that may block and what that would mean for ThreadPool resources. However, the ability to invoke multiple methods at once is not provided by the application I am building. It's possible that the application may provide some other limited functionality while the invoked method is running but the current requirements do not specify such functionality in detail. I anticipate that there would only be one long running thread in service at any time.
Is the use of Task.Run() for this type of method invocation a reasonable implementation? If not, what would a more reasonable implementation be that provides for the required criteria? Should I consider a dedicated thread outside of the ThreadPool for this invocation?
Is the use of Task.Run() for this type of method invocation a reasonable implementation?
Assuming that your "interface with hardware" can only be done using synchronous APIs, then yes, Task.Run is fine for that.
However, I would change when it's called. Right now, Task.Run is wrapping an async void method that executes on the thread pool (and uses Invoke to jump back on the UI thread). These are each problematic: Task.Run over async void will seem to complete "early" (i.e., at the first await); and using Invoke indicates that there's some tight coupling going on (UI calls background service which calls UI).
I would replace the async void with async Task and also change where Task.Run is used to avoid Invoke:
public async Task<int> GetInteger()
{
container.Controls.Clear();
container.Controls.Add(integerInput);
// Note: not `Result`, which will wrap exceptions.
return await integerInput.InputVal.Task;
}
public async Task MethodToInvokeAsync()
{
await Task.Run(...); // Interface with hardware...
// Block waiting on input
int val = await ui.GetInteger();
await Task.Run(...); // Interface with hardware some more...
}
var t = await (Task)method.Invoke(DemoInstance, args);

ContinueWith as an alternative to the await operator

My application uses scripts. So far, I've used C# for the scripts and compiled them using the CodeDomProvider. However, I've been thinking about switching to Lua using the NLua fork (a fork of the LuaInterface) because it's much easier to write scripts with plus I'm familiar with the syntax.
However, I'm facing a problem. Currently, I have an asynchronous method that returns a Task<bool>. It uses a TaskCompletionSource object and returns it's Result. That way, I can halt the execution of the script because it waits until the Result of the TaskCompletionSource object has been set, and only then returns this Result.
Now, with Lua - it's different. I obviously can't use the awaitoperator because it's a syntax of C# 5.0, and you can't use that in Lua. So that's why I'm asking if there's a workaround for this. I want to be able to achieve the same result as my old code (which is posted beneath this post) without having to use the awaitoperator. I've been told that I can do that with Task.ContinueWith, but I'm unfamiliar with this and the examples online are dull. If anyone can show me an example with my code, it'd be great.
Here's my method:
public async Task<bool> ReturnResult()
{
this.Response = new TaskCompletionSource<bool>();
return await this.Response.Task;
}
Here's the way I'm using it in my scripts:
var result = await ReturnResult();
The Result of the TaskCompletionSource object is set by another part of my code.
Basically, if you still failed to understand what I want to achieve - a method that halts it's execution until a response has been set by another part of the code. However, it has to be asynchronous, because I don't want my main thread to get stuck.
EDIT: Tried JonSkeet's suggestion and the code just runs without halting. Here's the full Script class.
public class Script
{
private Lua Lua { get; set; }
private TaskCompletionSource<bool> Response { get; set; }
public Script()
{
this.Lua = new Lua();
}
public void Run()
{
this.Lua.RegisterFunction("log", this, typeof(Script).GetMethod("Log"));
this.Lua.RegisterFunction("returnResult", this, typeof(Script).GetMethod("ReturnResult"));
this.Lua.DoFile(#"C:\test.lua");
}
public void SetResponse(bool response)
{
this.Response.SetResult(response);
}
public Task<bool> ReturnResult()
{
this.Response = new TaskCompletionSource<bool>();
return this.Response.Task;
}
public void Log(string text)
{
MessageBox.Show(text);
}
}
Here's the code of Form1:
public partial class Form1 : Form
{
private Script Script { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Script = new Script();
this.Script.Run();
}
private void button2_Click(object sender, EventArgs e)
{
this.Script.SetResponse(true);
}
}
Just throw two buttons and use the first one to run, second one to set response.
The Lua script is:
result = returnResult()
log("returned " .. result)
Download NLua from here.
Okay, as you now claim this has nothing to do with Lua, here's how you would call the method in C#, then log only when the task had completed:
Task<bool> task = ReturnResult();
task.ContinueWith(t => Log("Returned " + t.Result));
This does not halt execution at all - it just says that when the task returned from ReturnResult completes, it should call the logging code.
For production code, you would probably want to check whether the task was faulted, etc. There are overloads of ContinueWith which allow you to specify under which circumstances you want to run the continuation (only on success, only on fault etc), and you can add multiple continuations. But to get you going, the above is probably good enough.

creating a wrapper for a long synchronous operation to use eap, apm pattern and async/await

Suppose I have a service which will be doing a long, expensive synchronous operation, i.e.
class ExclamationMarkService
{
public string GetData(string param)
{
Thread.Sleep(5000);
return param + "!";
}
}
To wrap it to become asynchronous via the EAP pattern I can do this:
class ExclamationMarkServiceEAP
{
public delegate void GetDataHandler(string data);
public event GetDataHandler GetDataCompleted;
public void GetDataWorker(object param)
{
var service = new ExclamationMarkService();
string data = service.GetData((string)param);
if (GetDataCompleted != null)
{
GetDataCompleted(data);
}
}
public void GetData(string param)
{
var thread = new Thread(GetDataWorker) {IsBackground = true};
thread.Start(param);
}
}
A similar thing with the new async/await operators can be done this way:
class ExclamationMarkServiceTaskAsync
{
public async Task<string> GetDataAsync(string param)
{
var service = new ExclamationMarkService();
return await Task.Run(() => service.GetData(param));
}
}
Usage:
public static void CallExclamationMarkServiceEAP()
{
var service = new ExclamationMarkServiceEAP();
service.GetDataCompleted += service_GetDataCompleted;
service.GetData("hello EAP");
}
static void service_GetDataCompleted(string data)
{
Console.WriteLine(data);
}
public static async void CallExclamationMarkServiceTaskAsync()
{
var service = new ExclamationMarkServiceTaskAsync();
var data = await service.GetDataAsync("hello TaskAsync");
Console.WriteLine(data);
}
static void Main(string[] args)
{
CallExclamationMarkServiceEAP();
CallExclamationMarkServiceTaskAsync();
Console.Read();
}
In both cases I managed to offload the work to the background. In the case of EAP, by explicitly starting a thread. For the async/await version, by using Task.Run.
Questions:
How would an APM implementation of my ExclamationMarkService look like?
Given both EAP and APM versions, how can they be wrapped by using existing methods of the Task class (Task.Factory.StartNew / Task.Factory.FromAsync, etc.) so that they could be used with the async/await keywords.
Long running synchronous operations that are not IO bound do not belong in the ThreadPool. Running such operations in the ThreadPool exposes you to the risk of starvation, where the pool does not spin up threads fast enough to be responsive to the needs of the many other APIs that rely on it.
If you want to run something long-winded, run it on your own thread, being careful to marshall the result back to the right context if it needs to show in some UI.
As such your first approach seems more appropriate.
On the other hand, TPL offers the opportunity to hint that the task is long running, and allows the system to decide the best place to run it. It's as simple as:
Task.Factory.StartNew(someSyncAction, TaskCreationOptions.LongRunning)
StartNew returns a Task. You can await it.

Categories