Been doing quite a bit of silverlight programming lately and loving it but of course silverlight is async so i am forced to setup an event handler to call when the async is complete. This works great of course but i am just getting lots of code... basically 2 methods for everycall that i require to a wcf service. I recently discovered the following
client.LoadClientsCompleted += (sender, e) =>
{
// My Code
};
client.LoadClientsAsync(clientID);
It seems to work, its using lambdas rather than a physically method. I understand that this doesn't change the working of the technology and its still async. but it seems to tidy up my code quite a lot.
I would love to hear any comments on weather i should be using this, are there any PROS and CONS using either?
As i say point the event directly at a new method works great as well but technically i have 2 methods for every call i make ... The code is growing :-)
Using the lambda way i at least keep my callback event within my current method although it only fires when complete. It seems to make things easier BUT are there any problems with this method?
One big pro is that lambdas can capture the value of variables from their surroundings:
client.LoadClientsCompleted += (sender, e) =>
{
// My Code
// your code can use clientID here
};
client.LoadClientsAsync(clientID);
Related
I am working on a CoProcessFunction that uses a third party library for detecting certain patterns of events based on some rules. So, in the end, the ProcessElement1 method is basically forwarding the events to this library and registering a callback so that, when a match is detected, the CoProcessFunction can emit an output event. For achieving this, the callback relies on a reference to the out: Collector[T] parameter in ProcessElement1.
Having said that, I am not sure whether this use case is well-supported by Flink, since:
There might be multiple threads spanned by the third party library (let's say I have not any control over the amount of threads spanned, this is decided by the library)
I am not sure whether out might be recreated or something by Flink at some point, invalidating the references in the callbacks, making them crash
So far I have not observed any issues, but I have just run my program in the small. It would be great to hear from the experts whether my approach is correct and how could this be approached otherwise.
As an update based on Arvid's comments. Since my current process function already works well for me, except for the fact I don't have access to the mailbox executor, I have simply created a custom operator for injecting that:
class MyOperator(myFunction: MyFunction)
extends KeyedCoProcessOperator(myFunction)
{
private lazy val mailboxExecutor = getContainingTask
.getMailboxExecutorFactory
.createExecutor(getOperatorConfig.getChainIndex)
override def open(): Unit = {
super.open()
userFunction.asInstanceOf[MyFunction].mailboxExecutor = mailboxExecutor
}
}
This way I can register callbacks that will send mails to be processed one by one. In the main application I use it like this:
.transform("wrapping function in operator", new MyOperator(new MyFunction()))
So far everything looks good to me, but if you see problems or know a better way, it would be great to hear your thoughts on this again. In particular, the way of getting access to the mailbox executor is definitively a bit clumsy...
If you have asynchronous callbacks, you really should use asyncIO. So use your CoProcessFunction to emit a Tuple2 and have a asyncIO directly following it.
Op now added that he may not get a result back at all which makes asyncIO difficult to use. You could rely on the timeout to trigger such that the element gets removed but that may slow down processing as asyncIO has a limited queue of "active" elements.
So, the way to go in Flink 1.10 would probably to implement a custom operator using the MailboxExecutor.
Getting the executor is still a bit clumsy, but you could check AsyncWaitOperator and the AsyncWaitOperatorFactory.
Code sketch for using executor
// setup is optionally but if you use timestamped records, you usually do that
void setup(StreamTask<?, ?> containingTask, StreamConfig config, Output<StreamRecord<OUT>> output) {
super.setup(containingTask, config, output);
this.timestampedCollector = new TimestampedCollector<>(output);
}
void processElement(record) {
externalLib.addElement(record, (match) -> {
mailboxExecutor.execute(() -> {
timestampedCollector.collect(match);
});
});
}
Note that this involves quite a bit #PublicEvolving code and we already have some changes on our agenda. So be prepared to adjust code for 1.11.
Dart has many ways of creating, processing and returning async functions. One of the most common methods is to:
import 'dart:async';
var completer = new Completer();
// Previously this would have been new Timer(0, () => ....);
Timer.run(() => completer.complete(doSomethingHere()));
return completer.future;
However dart also provides a constructor for Future's directly such as:
import 'dart:async';
return new Future.of(() => doSomethingHere());
I am aware that the Timer.run() version may be cancelled using the return value of the static method. And that the new Future.of() version is slightly less code, is there a particular benefit to using new Future.of() over Timer.run() (or vice versa). Or are the benefits simply those that I just mentioned?
Future.of returns a Future, Timer.run does not return anything. To me, this is the main difference.
I use Future.of if I want to return a value as a Future.
I use Timer.run if I want to run some function later, and I don't care about the value that it produces.
One big difference is when the function is run, though.
For Future.of, the function is run in the current event loop, and only its value is made available in the next event loop.
For Timer.run, the function is run in the next event loop.
Don't forget that they are two different things. Timer can be used anywhere for so many purposes. It could be used on the client-side for waiting for layout to happen before running more code, for example. So, it may not have anything to do with futures. I use the timer sometimes in client-side code to wait for a layout.
Timer is a generic class for delaying the running of some code. No matter whether it has anything to do with futures or not. Another example could be client-side animations. Nothing to do with futures or dealing with data asynchronously.
Futures, however, are monads that help you to program asynchronous programs. Basically a replacement to passing plain callback functions.
Use new Future.of() when writing asynchronous programs and it suits your situation (the same goes with new Future.immediate().
Use the Timer class if you want to delay the running of some code.
If what you want to do is to use futures for asynchronous programming and at the same time delay the code, forget the timer class unless you need some real delay (more than 0/next event).
I am using Prism's event aggregator in Silverlight and am having a hard time with Subscribe. When the code hits the Subscribe method it just hangs and never makes it to the next line of code. If I break up the code, _eventAggregator.GetEvent() seems to return a valid instance of the event. The code definitely hangs on "Subscribe". What could I be doing wrong here? The JobCompletedEvent is declared in another library (which is a dependency for this library).
public void CallMeWhenTheJobIsDone(Action callback)
{
if (_jobIsRunning)
_eventAggregator.GetEvent<JobCompletedEvent>().Subscribe((e) => callback(), ThreadOption.UIThread);
else
callback();
}
public class JobCompletedEvent: Microsoft.Practices.Prism.Events.CompositePresentationEvent<JobCompleted>
{ }
public class JobCompleted
{
}
1) Why you using if (_jobIsRunning) ?? You calling callback in any case.
2) Prism will only bring you the event - and according to your question - Prism IS rising and passing the event to you - so it's not a Prism question - it seems that whatever called by callback is not working.
So we need to see more on what is called by callback and another thing: in Prism case you calling the callback on ThreadOption.UIThread ThreadPool so - double check if any other thread already lock the UI thread when you calling callback
My problem is that I should not have used an anonymous method in my subscribe. Prism does not seem to support it. Some are calling this a bug in Prism, I agree :) Not only can you not use an anonymous method but the method must be public.
Some references I found googling
http://greenicicleblog.com/2010/04/28/prism-event-aggregator-more-leaky-than-it-seems/
Execute same Prism Command from different ViewModels
I suspect this is in the Prism docs somewhere, I guess I just blew by it. If I set keepSubscriberReferenceAlice it works with the private method or anonymous method (which does make some sense now that I think about it). The funny thing is that in my sandbox project I cannot even compile with an anonymous method which uses privately scoped code. My live project allows it to compile but fails at runtime.
Edit:
Yup, it is in the docs
http://msdn.microsoft.com/en-us/library/ff921122%28v=pandp.40%29.aspx
Big yellow box 2/3 of the way down the page.
I'm fairly new to MVVM, so please excuse me if this problem has a well-known solution.
We are building a bunch of model classes which have some core properties that are loaded up-front, as well as some additional properties which could be lazy-loaded on demand by making a web API call (update: to clarify, it would be a web API call per lazily-loaded property).
Rather than having multiple models, it seems sensible to have a single model with the lazy-loading logic in there. However, it also seems that the lazy-loaded properties should not block when accessed, so that when the View binds to the ViewModel and it binds to the Model, we don't block the UI thread.
As such, I was thinking of a pattern something along the lines of when a lazy property on the Model is accessed it begins an asynchronous fetch and then immediately returns a default value (e.g. null). When the asynchronous fetch is complete, it will raise a PropertyChanged event so that the ViewModel/View can re-bind to the fetched value.
I've tried this out and it seems to work quite nicely, but was wondering:
Are there any pitfalls to this approach that I haven't found out about yet, but will run into as the app increases in complexity?
Is there an existing solution to this problem either built into the framework, or which is widely used as part of a 3rd party framework?
I did something like this in the past and the one thing I kept forgetting about is you can't call your async property through any kind of code behind and expect it to have a value.
So if I lazy-load a list of Customer.Products, I can't reference Customer.Products.Count in the code-behind because the first time it's called the value is NULL or 0 (depending on if I create a blank collection or not)
Other than that, it worked great for the bindings. I was using the Async CTP library for making my async calls, which I found was absolutely wonderful for something like this.
public ObservableCollection<Products> Products
{
get
{
if (_products == null)
LoadProductsAsync();
return _products;
}
set { ... }
}
private async void LoadProductsAsync()
{
Products = await DAL.LoadProducts(CustomerId);
}
Update
I remember another thing I had issues with was data that actually was NULL. If Customer.Products actually returned a NULL value from the server, I needed to know that the async method had run correctly and that the actual value was null so that it didn't re-run the async method.
I also didn't want the async method to get run twice if someone called the Get method a 2nd time before the first async call had completed.
I solved this at the time by having an Is[AsyncPropertyName]Loading/ed property for every async property and setting it to true during the first async call, but I wasn't really happy about having to create an extra property for all async properties.
So let's say I have a test that looks something like
[TestMethod]
[Asynchronous]
public void MyTest() {
MyObject m = new MyObject();
m.DoAsyncStuff();
EnqueueConditional(() => m.TaskComplete);
EnqueueCallback(() => Assert.IsTrue(m.ValidState));
EnqueueTestComplete();
}
How does EnqueueConditional work? Assume MyObject has no property change notifiers or anything. I'm assuming EnqueueConditional polls the variable periodically? But I'm not sure.
That's precisely what it does. It polls the m.TaskComplete variable multiple times a second (I'm not sure how many). It's a hack, and you wouldn't want it in production code, but it works for a testing framework, and it sure as heck simplifies a lot of other code.
For example, in production code, you'd probably want to make MyObject implement INotifyPropertyChanged, and then use Reactive Extensions to subscribe to the INPC notifications. But that would be a lot of extra work for the sort of simple conditionals that are everywhere in testing code, and I think that Jeff Wilcox made the right call in how he implemented this, however hacky it might be.