given a List<Message> i send out the first message with my Send(message). Now I would like to wait for (an asynchronous) response to come back before i send out the next message...
Block until notified 'old' way
i know how to implement an event-based solution for this situation, using thread locking / with Monitor.Wait and Monitor.Pulse
Reactive 'new' way?
But I was wondering whether it would make sense to utilize Reactive Extensions here?
If Rx would convey worthwhile benefits here then how could I make the response reactively gate the next send invocation? Obviously it would involve IObservable, probably two as primary sources, but then what?
The question is not very specific and seems to be very general in the sense that you have not mentioned what is the sender receiver etc, so the answer would also be very general :)
var receiveObs = //You have created a observable around the receive mechanism
var responses = messages.Select(m => {
send(m);
return receiveObs.First();
}).ToList();
I think Rx is a good choice here, but I think I could be missing something in your requirements. From what I understand Rx provides a very simple solution.
If you already have a list of messages then you can send them reactively like so:
messages
.ToObservable()
.ObserveOn(Scheduler.ThreadPool)
.Subscribe(m =>
{
Send(m);
});
This pushes the calls to Send to the thread-pool and, by the built-in behaviour of observables, each call to Send waits until the previous call is completed.
Since this is all happening on a different thread your code is non-blocking.
The extra benefit of Rx is that you wouldn't need to change the behaviour or signature of your Send method to make this work.
Simple, huh?
I tested this and it worked fine given my understanding of your problem. Is this all you need or is there something I missed?
I'm not sure Rx is a good fit here. Rx is based on the concept of "push collections", i.e. pushing data to consumers instead of pulling it. What you want is pull the first item, send it asynchronously, and continue with the next element when the asynchronous operation finished. For this kind of job, the perfect tool would be async / await*!
async void SendMessages(List<Message> messages)
{
foreach (Message message in messages)
{
await SendAsync(message);
}
}
with
Task SendAsync(Message message);
* available in the Async CTP or the .NET 4.5 Preview
Assuming your Send method follows the APM model, the following approach should work for you
List<Message> messages;
IObservable<Response> xs;
xs = messages.ToObservable().SelectMany(msg => Observable.FromAsyncPattern(Send, msg));
Edit - this won't work as Anderson has suggested, here's an example showing the problem
Func<int,string> Send = (ii) => { "in Send".Dump(); Thread.Sleep(2000); return ii.ToString(); };
Func<int,IObservable<string>> sendIO = Observable.FromAsyncPattern<int,string>(Send.BeginInvoke, Send.EndInvoke);
(new [] { 1, 2, 3 }).ToObservable().SelectMany(sendIO).Dump();
Related
I am trying to learn how to work with Zenject's and unity and I have encountered a particular problem that I do not know if it has a possible solution solely using Zenject's api.
Let assume i have MethodA, MethodB and MethodC, and a SignalA.
Is it possible to make this sequence:
SignalA.Fire() => MethodA (until released/finished)
=> MethodB (until released/finished)
=> MethodC (until released/finished)
Right now i have this pice of code :
private void BindSignalA()
{
Container.DeclareSignal<SignalA>().RunSync();
Container.BindSignal<SignalA>().ToMethod<MethodA>(handler => handler.Execute).FromNew();
Container.BindSignal<SignalA>().ToMethod<MethodB>(handler => handler.Execute).FromNew();
Container.BindSignal<SignalA>().ToMethod<MethodC>(handler => handler.Execute).FromNew();
}
And MethodA looks like this :
public class MethodA
{
public async void Execute()
{
await new WaitUntil(() => false);
}
}
So the expected result is that MethodB and MethodC will be never executed.
But the actual result is that all Methods are executed.
Is there a solution using Zenject's api to make this happen?
Thanks for the help, and in case any more information is needed I would love to know.
I am not familiar with signals, but checking the documentation , mainly the the 3rd point into consideration maybe your case is not good scenario for signal use.
When To Use Signals
Signals are most appropriate as a communication mechanism when:
There might be multiple interested receivers listening to the signal
The sender doesn't need to get a result back from the receiver
The sender doesn't even really care if it gets received. In other words, the sender should not rely on some state changing when the signal is called for subsequent sender logic to work correctly. Ideally signals can be thought as "fire and forget" events
The sender triggers the signal infrequently or at unpredictable times
On the other hand I you might be confusing decoupling the code with the syncronous execution concept. Delegates or events (which are a specific type of delegate) are spare pieces of logic of one class that you can keep so that can be executed in other class, so that you can "subscribe" or "listen" to something that might happen to execute/invoke your event in other part of the code. However that does not involve any asyncronous code or multithreading.
As far as I can guess, signals are used to handle event subscription/invocation in a decoupled manner with the Zenject signal object, in a similar way as dependencies between classes are handled in a decoupled manner with interfaces, so first I would check if your case is suitable for their use checking the documentation carefully and following the examples provided along until the concept clicks.
Meanwhile, I would first try to use c# normal delegates so that after the zenject signal misson can be understood. Also providing a simple working example of what you are trying to do without zenject would be very helpful as departing point to achieve the zenject way of achieving that same thing.
I'm trying to wrap my head around the new async/await functionality in combination with webapi.
What I would like to do is the following:
I'm receiving a (POST) request on a controller (A) on a certain endpoint.
This controller does nothing but just sends this request through to a second controller (B) on another endpoint (don't ask me why - just a thought experiment).
Let's say B does some long-running work (retrieve data from somewhere) and stores the result in the database.
I don't want to wait on the work from B before I can return a OK message to the request that was sent to A. I would like to be able to call A and get OK back ASAP while the work is still being completed on B.
Is this even possible? If so, what would be a correct way to design something like this?
Thanks for any pointers you might give me.
What you want is to trigger a "Fire and Forget" semantics on your call.
If you're using .NET 4.5.2, you can use HostingEnvironment.QueueBackgroundWorkItem to register and queue work on a ASP.NET Threadpool thread.
If you're on previous versions, you can use BackgroundTaskManager by Stephan Cleary.
Note this has nothing to do with async-await.
An example would look like this:
public HttpResponseMessage Foo()
{
HostingEnvironment.QueueUserWorkItem(() => { /* offloaded code here */ });
return Request.CreateResponse(HttpStatusCode.OK);
}
Just an assumptioin based out of the async/await concept explained by John Skeet. The async/await pattern uses continuations which maintain the state machine. Basically the frame work is supposed to execute the instructions till the end of the synchronous methods.
When it encounters the async call instructions, it invokes it and if the result is readily available goes to the next steps and does the processing. If it does not have the result immediately after the call, it returns back from the method leaving this to be taken care by the framework. So in your case, I think practically it would return immediately if you have no code. But if you have any long running code, it should return leaving the job to the background framework thread but result may come back later.
If your objective is to make sure you don't block the foreground, then this will be achieved with the first controller itself. But even in your case, the second controller wouldn't block the UI. To your question on whether this is right or wrong, I am sure because you may have some reasons why you are thinking of such a pattern.
There are numerous experts here. Correct me if my interpretation is wrong, please:)
You start the background work and respond immediately. The async pattern is only to be used in case you have to respond in any way on the result of the long running task and prevent blocking of the calling thread.
i.e:
public bool ControllerAMethod(byte[] somedata)
{
Task.Factory.StartNew(() =>
{
ControllerB.SendData(somedata);
});
return true;
}
You probably want to respond to the caller with a response code of 202 (accepted) to indicate to the client that some other processing is ongoing.
Then if your client needs additional feedback it could do a long poll, or you could implement a websocket, etc.
I have tried to simplify my issue by a sample code here. I have a producer thread constantly pumping in data and I am trying to batch it with a time delay between batches so that the UI has time to render it. But the result is not as expected, the produce and consumer seems to be on the same thread.
I don't want the batch buffer to sleep on the thread that is producing. Tried SubscribeOn did not help much. What am I doing wrong here, how do I get this to print different thread Ids on producer and consumer thread.
static void Main(string[] args)
{
var stream = new ReplaySubject<int>();
Task.Factory.StartNew(() =>
{
int seed = 1;
while (true)
{
Console.WriteLine("Thread {0} Producing {1}",
Thread.CurrentThread.ManagedThreadId, seed);
stream.OnNext(seed);
seed++;
Thread.Sleep(TimeSpan.FromMilliseconds(500));
}
});
stream.Buffer(5).Do(x =>
{
Console.WriteLine("Thread {0} sleeping to create time gap between batches",
Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(TimeSpan.FromSeconds(2));
})
.SubscribeOn(NewThreadScheduler.Default).Subscribe(items =>
{
foreach (var item in items)
{
Console.WriteLine("Thread {0} Consuming {1}",
Thread.CurrentThread.ManagedThreadId, item);
}
});
Console.Read();
}
Understanding the difference between ObserveOn and SubscribeOn is key here. See - ObserveOn and SubscribeOn - where the work is being done for an in depth explanation of these.
Also, you absolutely don't want to use a Thread.Sleep in your Rx. Or anywhere. Ever. Do is almost as evil, but Thead.Sleep is almost always totally evil. Buffer has serveral overloads you want to use instead - these include a time based overload and an overload that accepts a count limit and a time-limit, returning a buffer when either of these are reached. A time-based buffering will introduce the necessary concurrency between producer and consumer - that is, deliver the buffer to it's subscriber on a separate thread from the producer.
Also see these questions and answers which have good discussions on keeping consumers responsive (in the context of WPF here, but the points are generally applicable).
Process lots of small tasks and keep the UI responsive
Buffer data from database cursor while keeping UI responsive
The last question above specifically uses the time-based buffer overload. As I said, using Buffer or ObserveOn in your call chain will allow you to add concurrency between producer and consumer. You still need to take care that the processing of a buffer is still fast enough that you don't get a queue building up on the buffer subscriber.
If queues do build up, you'll need to think about means of applying backpressure, dropping updates and/or conflating the updates. These is a big topic too broad for in depth discussion here - but basically you either:
Drop events. There have been many ways discussed to tackle this in Rx. I current like Ignore incoming stream updates if last callback hasn't finished yet but also see With Rx, how do I ignore all-except-the-latest value when my Subscribe method is running and there are many other discussions of this.
Signal the producer out of band to tell it to slow down or send conflated updates, or
You introduce an operator that does in-stream conflation - like a smarter Buffer that could compress events to, for example, only include the latest price on a stock item etc. You can author operators that are sensitive to the time that OnNext invocations take to process, for example.
See if proper buffering helps first, then think about throttling/conflating events at the source as (a UI can only show so much infomation anway) - then consider smarter conflation as this can get quite complex. https://github.com/AdaptiveConsulting/ReactiveTrader is a good example of a project using some advanced conflation techniques.
Although the other answers are correct, I'd like to identify your actual problem as perhaps a misunderstanding of the behavior of Rx. Putting the producer to sleep blocks subsequent calls to OnNext and it seems as though you're assuming Rx automatically calls OnNext concurrently, but in fact it doesn't for very good reasons. Actually, Rx has a contract that requires serialized notifications.
See §§4.2, 6.7 in the Rx Design Guidelines for details.
Ultimately, it looks as though you're trying to implement the BufferIntrospective operator from Rxx. This operator allows you to pass in a concurrency-introducing scheduler, similar to ObserveOn, to create a concurrency boundary between a producer and a consumer. BufferIntrospective is a dynamic backpressure strategy that pushes out heterogeneously-sized batches based on the changing latencies of an observer. While the observer is processing the current batch, the operator buffers all incoming concurrent notifications. To accomplish this, the operator takes advantage of the fact that OnNext is a blocking call (per the §4.2 contract) and for that reason this operator should be applied as close to the edge of the query as possible, generally immediately before you call Subscribe.
As James described, you could call it a "smart buffering" strategy itself, or see it as the baseline for implementing such a strategy; e.g., I've also defined a SampleIntrospective operator that drops all but the last notification in each batch.
ObserveOn is probably what you want. It takes a SynchronizationContext as an argument, that should be the SynchronizationContext of your UI. If you don't know how to get it, see Using SynchronizationContext for sending events back to the UI for WinForms or WPF
I am trying to better understand the Async and the Parallel options I have in C#. In the snippets below, I have included the 5 approaches I come across most. But I am not sure which to choose - or better yet, what criteria to consider when choosing:
Method 1: Task
(see http://msdn.microsoft.com/en-us/library/dd321439.aspx)
Calling StartNew is functionally equivalent to creating a Task using one of its constructors and then calling Start to schedule it for execution. However, unless creation and scheduling must be separated, StartNew is the recommended approach for both simplicity and performance.
TaskFactory's StartNew method should be the preferred mechanism for creating and scheduling computational tasks, but for scenarios where creation and scheduling must be separated, the constructors may be used, and the task's Start method may then be used to schedule the task for execution at a later time.
// using System.Threading.Tasks.Task.Factory
void Do_1()
{
var _List = GetList();
_List.ForEach(i => Task.Factory.StartNew(_ => { DoSomething(i); }));
}
Method 2: QueueUserWorkItem
(see http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx)
You can queue as many thread pool requests as system memory allows. If there are more requests than thread pool threads, the additional requests remain queued until thread pool threads become available.
You can place data required by the queued method in the instance fields of the class in which the method is defined, or you can use the QueueUserWorkItem(WaitCallback, Object) overload that accepts an object containing the necessary data.
// using System.Threading.ThreadPool
void Do_2()
{
var _List = GetList();
var _Action = new WaitCallback((o) => { DoSomething(o); });
_List.ForEach(x => ThreadPool.QueueUserWorkItem(_Action));
}
Method 3: Parallel.Foreach
(see: http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx)
The Parallel class provides library-based data parallel replacements for common operations such as for loops, for each loops, and execution of a set of statements.
The body delegate is invoked once for each element in the source enumerable. It is provided with the current element as a parameter.
// using System.Threading.Tasks.Parallel
void Do_3()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
Parallel.ForEach(_List, _Action);
}
Method 4: IAsync.BeginInvoke
(see: http://msdn.microsoft.com/en-us/library/cc190824.aspx)
BeginInvoke is asynchronous; therefore, control returns immediately to the calling object after it is called.
// using IAsync.BeginInvoke()
void Do_4()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
_List.ForEach(x => _Action.BeginInvoke(x, null, null));
}
Method 5: BackgroundWorker
(see: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)
To set up for a background operation, add an event handler for the DoWork event. Call your time-consuming operation in this event handler. To start the operation, call RunWorkerAsync. To receive notifications of progress updates, handle the ProgressChanged event. To receive a notification when the operation is completed, handle the RunWorkerCompleted event.
// using System.ComponentModel.BackgroundWorker
void Do_5()
{
var _List = GetList();
using (BackgroundWorker _Worker = new BackgroundWorker())
{
_Worker.DoWork += (s, arg) =>
{
arg.Result = arg.Argument;
DoSomething(arg.Argument);
};
_Worker.RunWorkerCompleted += (s, arg) =>
{
_List.Remove(arg.Result);
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
};
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
}
}
I suppose the obvious critieria would be:
Is any better than the other for performance?
Is any better than the other for error handling?
Is any better than the other for monitoring/feedback?
But, how do you choose?
Thanks in advance for your insights.
Going to take these in an arbitrary order:
BackgroundWorker (#5)
I like to use BackgroundWorker when I'm doing things with a UI. The advantage that it has is having the progress and completion events fire on the UI thread which means you don't get nasty exceptions when you try to change UI elements. It also has a nice built-in way of reporting progress. One disadvantage that this mode has is that if you have blocking calls (like web requests) in your work, you'll have a thread sitting around doing nothing while the work is happening. This is probably not a problem if you only think you'll have a handful of them though.
IAsyncResult/Begin/End (APM, #4)
This is a widespread and powerful but difficult model to use. Error handling is troublesome since you need to re-catch exceptions on the End call, and uncaught exceptions won't necessarily make it back to any relevant pieces of code that can handle it. This has the danger of permanently hanging requests in ASP.NET or just having errors mysteriously disappear in other applications. You also have to be vigilant about the CompletedSynchronously property. If you don't track and report this properly, the program can hang and leak resources. The flip side of this is that if you're running inside the context of another APM, you have to make sure that any async methods you call also report this value. That means doing another APM call or using a Task and casting it to an IAsyncResult to get at its CompletedSynchronously property.
There's also a lot of overhead in the signatures: You have to support an arbitrary object to pass through, make your own IAsyncResult implementation if you're writing an async method that supports polling and wait handles (even if you're only using the callback). By the way, you should only be using callback here. When you use the wait handle or poll IsCompleted, you're wasting a thread while the operation is pending.
Event-based Asynchronous Pattern (EAP)
One that was not on your list but I'll mention for the sake of completeness. It's a little bit friendlier than the APM. There are events instead of callbacks and there's less junk hanging onto the method signatures. Error handling is a little easier since it's saved and available in the callback rather than re-thrown. CompletedSynchronously is also not part of the API.
Tasks (#1)
Tasks are another friendly async API. Error handling is straightforward: the exception is always there for inspection on the callback and nobody cares about CompletedSynchronously. You can do dependencies and it's a great way to handle execution of multiple async tasks. You can even wrap APM or EAP (one type you missed) async methods in them. Another good thing about using tasks is your code doesn't care how the operation is implemented. It may block on a thread or be totally asynchronous but the consuming code doesn't care about this. You can also mix APM and EAP operations easily with Tasks.
Parallel.For methods (#3)
These are additional helpers on top of Tasks. They can do some of the work to create tasks for you and make your code more readable, if your async tasks are suited to run in a loop.
ThreadPool.QueueUserWorkItem (#2)
This is a low-level utility that's actually used by ASP.NET for all requests. It doesn't have any built-in error handling like tasks so you have to catch everything and pipe it back up to your app if you want to know about it. It's suitable for CPU-intensive work but you don't want to put any blocking calls on it, such as a synchronous web request. That's because as long as it runs, it's using up a thread.
async / await Keywords
New in .NET 4.5, these keywords let you write async code without explicit callbacks. You can await on a Task and any code below it will wait for that async operation to complete, without consuming a thread.
Your first, third and forth examples use the ThreadPool implicitly because by default Tasks are scheduled on the ThreadPool and the TPL extensions use the ThreadPool as well, the API simply hides some of the complexity see here and here. BackgroundWorkers are part of the ComponentModel namespace because they are meant for use in UI scenarios.
Reactive extensions is another upcoming library for handling asynchronous programming, especially when it comes to composition of asynchronous events and methods.
It's not native, however it's developed by Ms labs. It's available both for .NET 3.5 and .NET 4.0 and is essentially a collection of extension methods on the .NET 4.0 introduced IObservable<T> interface.
There are a lot of examples and tutorials on their main site, and I strongly recommend checking some of them out. The pattern might seem a bit odd at first (at least for .NET programmers), but well worth it, even if it's just grasping the new concept.
The real strength of reactive extensions (Rx.NET) is when you need to compose multiple asynchronous sources and events. All operators are designed with this in mind and handles the ugly parts of asynchrony for you.
Main site: http://msdn.microsoft.com/en-us/data/gg577609
Beginner's guide: http://msdn.microsoft.com/en-us/data/gg577611
Examples: http://rxwiki.wikidot.com/101samples
That said, the best async pattern probably depends on what situation you're in. Some are better (simpler) for simpler stuff and some are more extensible and easier to handle when it comes to more complex scenarios. I cannot speak for all the ones you're mentioning though.
The last one is the best for 2,3 at least. It has built-in methods/properties for this.
Other variants are almost the same, just different versions/convinient wrappers
In my opinion, I have a pretty good "feel" for RX functions - I use many of them or can imagine how other can be useful - but I can't find a place for the .Prune function. I know that this is a Multicast to AsyncSubject, but how this can be useful in a real scenario?
Edit: Richard says WebRequest is a good candidate for Prune(). I still don't see how. Let's take an example - I want to transform incoming uri's to images:
public static IObservable<BitmapImage> ToImage(this IObservable<string> source)
{
var streams =
from wc in source.Select(WebRequest.Create)
from s in Observable
.FromAsyncPattern<WebResponse>(wc.BeginGetResponse,
wc.EndGetResponse)()
.Catch(Observable.Empty<WebResponse>())
select s.GetResponseStream();
return streams
.ObserveOnDispatcher()
.Select(x =>
{
var bmp = new BitmapImage();
bmp.SetSource(x);
return bmp;
});
}
I don't see it necessary to append .Prune to .FromAsyncPattern, because when you're calling FromAsyncPattern() (which is hot) you subscribe "instantly".
As it was confirmed on the RX Forum Prune is just a covenience operator.
If your observable has a single value and you're publishing it, can replace Publish\Connect with a single call to .Prune()
So from my experience, the most common scenario for Prune is:
You have a cold observable that produces side-effects and emits only one value
You have more than one subscriber to that observable, so you want to make it hot (because of side-effects)
Another, pointed out in the forum, is when you need to cache a particular value on a hot observable(usually first). Then you use FromEvent(...).Take(1).Prune() and anybody who subscribes to this will get the same value guaranteed. This one is not just "convenience", but pretty much the only easy way to achieve the result.
Pretty useful, after all!
The most common scenario is when the source observable is hot and can complete before you subscribe to it. The AsyncSubject captures the last value and re-emits it for any future subscribers.
Edit
I'd have to check, but I believe FromAsyncPattern uses an AsyncSubject internally, so is actually already "Pruned".
However, assuming you were working with some other hot source that did not, the use of Prune comes entirely down to the lifetime of the IObservable before it is subscribed to. If you subscribe to it instantly, there is no need for Prune. If the IObservable will exist for a while before being subscribed to, however, it may have already completed.
This is my understanding, as someone who has ported Rx but never used Prune. Maybe you should ask the same question on the Rx forums? You've got a chance of it being answered by someone on the Rx team.
I've also found a neat use for it when I've got multiple UI components that need to listen to a task (e.g. callback) and by default, Subscribe() on a cold observable will kick off that task several times which is typically not what you want when sharing state across UI components.
I know Richard mentioned a lot of these points but I figured this is such a perfect candidate for single-run Tasks, to add this example in too.
var oTask = Observable.FromAsync(() => Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
Console.WriteLine("Executed Task");
}));
//Setup the IConnectedObservable
var oTask2 = oTask.PublishLast();
//Subscribe - nothing happens
oTask2.Subscribe(x => { Console.WriteLine("Called from Task 1"); });
oTask2.Subscribe(x => { Console.WriteLine("Called from Task 2"); });
//The one and only time the Task is run
oTask2.Connect();
//Subscribe after the task is already complete - we want the results
Thread.Sleep(5000);
oTask2.Subscribe(x => { Console.WriteLine("Called from Task 3"); });