Catel's AsynchronousCommand correct usage - catel

I've to call an async Task using a command. I tought that AsynchronousCommand would have done the trick but it accepts an Action as method so I've to use something as
public async void Something(object args)
would it be supposed to accept a Task on Command's definition?
UPDATE #1
Used TaskCommand as suggested by #Geert

Async void is very bad, because it cannot be awaited (meaning you can cause a lot of issues). Either use async Task ExecuteAsync or void Execute.

Related

Can a C# Azure function create another thread?

Inside an Azure function I have to start a new thread and wait for its results by checking a status variable in a While loop. Once the thread completed its execution, the function will proceed to the end.
Is it a legitimate way of programming Azure functions?
What will happen to my function app if While loop doesn't break or a thread doesn't return?
Yes, you can but you should use Durable Functions for this which are a set of premade libraries that were made specifically for such cases.
There are quite a few patterns that range from human intervention, orchestration and such.
Your code might look something like this as per their examples:
[FunctionName("BudgetApproval")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
bool approved = await context.WaitForExternalEvent<bool>("Approval");
if (approved)
{
// approval granted - do the approved action
}
else
{
// approval denied - send a notification
}
}
Or another option is you make a durable entity function that holds the state and then an event when that changes. Or a monitor function which basically loops around to see if state has changed. There are plenty of options

Where Isolate can be defined in Flutter? How to start a thread in Flutter?

I am a new in Flutter, so the question can be kind of obvious, but I can't find any answer on the Internet.
I have a Flutter application with some screens and I would say on the fifth screen I have a button, which should trigger some heavy computation work (converting thousands of images). On the same screen there is a progress bar and it is supposed to display the progress.
I am puzzled how to implement that technically. The triggering is happening obviously on onPressed of the button.
if I simply call a Future<void> function, then the UI is freezing completely for the time of processing, which is obviously is not desired behavior
if I put my function inside compute, on the first await I get exception
Unhandled Exception: Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized. If you're running an application and need to access the binary messenger before runApp() has been called (for example, during plugin initialization), then you need to explicitly call the WidgetsFlutterBinding.ensureInitialized() first. which puzzles me, because I call WidgetsFlutterBinding.ensureInitialized() before runApp(). Anyway this method is not working.
compute(computationFunction, 'argument');
// ...
static void computationFunction(String argument) async {
await firstStepFunction();
// ...
if I put my function into Isolate.spawn I get exception Unhandled Exception: Invalid argument(s): Isolate.spawn expects to be passed a static or top-level function which is also puzzling me. I tried to make the function static and moved the function to the top level of this fifth screen module. Nothing changed. Am I supposed to start the Isolate at the main function? In all beautiful examples it is done like that. Can't I start the Isolate in the middle by the button click.
Isolate.spawn(computationFunction, receivePort.sendPort);
// ...
void computationFunction(SendPort sendPort) async {
await firstStepFunction();
// ...
In Java I think a simple new Thread(...).start() will do the job.
But how to do it in Flutter?
Update:
In my experiments I've noticed, that neither Flutter Hot Restart nor Hot Reload are not working correctly with isolates. You need really to run again the whole app.
I managed to start Isolate.spawn all right if async/await keywords are removed. Off course the called function should have its synchronous version. So this does not work universally.
Isolate.spawn(computationFunction, receivePort.sendPort);
// ...
static void computationFunction(SendPort sendPort) { // async removed
firstStepFunctionSync(); // the function is replaced with its synchronous version
// ...
I've found package flutter_isolate which allows to run the async functions:
FlutterIsolate.spawn(computationFunction, argument);
// ...
void computationFunction(SendPort sendPort) async {
await firstStepFunction();
// ...
I will try to use flutter_isolate package in my prototype.
You should read https://dev.to/alphamikle/why-should-you-use-isolates-in-flutter-1k5o, and look at package:isolates.
The article contrasts using main thread, compute, Isolate proper, and the isolates package, with advantages and disadvantages of each. Best article I've seen in a long time.
Also keep in mind, Java threads are data-shared, leading to possible deadlocks. Dart isolates are share-nothing, using "ports" to carefully move data between isolates, and no need for locking!
Check out this plugin, which provides an easy way to work with isolates with a worker abstraction or using Parallel methods, and has well-explained documentation.
https://pub.dev/packages/easy_isolate
The use is simple as
void main() async {
final worker = Worker();
await worker.init(mainHandler, isolateHandler);
worker.sendMessage(null);
}
void mainHandler(dynamic data, SendPort isolateSendPort) {
isolateSendPort.send(null);
}
// Top-level function (or static)
void isolateHandler(dynamic data, SendPort mainSendPort, SendErrorFunction onSendError) {
mainSendPort.send(null);
}
Or using the Parallel methods
Future main() async {
await Parallel.foreach(['test'], writeFile);
}
// Top-level function (or static)
void writeFile(String name) {
File(Directory.systemTemp.path + '/$name').createSync();
}

GatewayProxyFactoryBean doesn't consider Future<Void> as a no-reply method

Looking at the message gateway methods return type semantics, the void return type indicates no reply is produced (no reply channel will be created), and the Future return type indicates asynchronous invocation mode (utilizing AsyncTaskExecutor).
Now, if one wishes to combine those two and make the no-reply method asynchronous, one could argue that the mere possibility of declaring a return type of Future<Void> would mean just that: the method is invoked asynchronously (by declaring a Future), and the method doesn't expect any reply (by declaring a type parameter Void).
Looking at the source code of GatewayProxyFactoryBean, it is clear this is not the case:
private Object invokeGatewayMethod(MethodInvocation invocation, boolean runningOnCallerThread) throws Exception {
...
boolean shouldReply = returnType != void.class;
...
Only the simple void return type is checked. So I'm wondering if this is a feature or a bug. If this is a feature, the Future<Void> return type is not behaving as one could be led to expect, and (in my opinion) should be handled differently (causing a validation error or something similar).
It's not clear what is the point of returning a Future<Void> in this case.
The reason we can't treat Future<Void> as "special" is that the downstream flow might return such an object; the framework can't imply intent.
If you want to run a flow that doesn't return a reply asynchronously, simply make the request channel an ExecutorChannel; if you are using XML configuration, documentation is here.
If you are using java configuration define the channel #Bean with type ExecutorChannel.

Monotouch PerformSelector on specific thread with multiple arguments and callbacks

I've been having some issues with threading in monotouch. My app makes use of an external library which I've linked with and it works fine. Because of the nature of the app and the library I have to make all the calls to it on a single separate thread.These calls will generally be :
Random non deterministic caused by user
Every t miliseconds(around 20ms). Like an update function
After reading for a bit I decided to try out NSThread. I've managed to call the Update function by attaching an NSTimer to the thread's RunLoop and it's all working fine. The problem that I'm having now is calling other methods on the same thread. I read somewhere that using PerformSelector on the RunLoop adds the selector invocation to the RunLoop's queue and invokes it when available, which is basically exactly what I need. However the methods that I need to call :
Can have multiple paramteres
Have callbacks, which I need to invoke on the main thread, again with multiple parameters
For the multiple parameters problem I saw that NSInvocation can be a solution, but the life of me I can't figure out how to do it with monotouch and haven't found any relevant examples.
For the actuals calls that I need to make to the library, I tried doing a generic way in which I can call any function I choose via delegates on a particular thread, which sort of works until I'm hit with the multiple parameters and/or callbacks to the main thread again with multiple parameters. Should I maybe just register separate selectors for each (wrapped)function that I need to call from the library?
I'm not hellbent on using this approach, if there is a better way I'm open to it, it's just that after searching for other options I saw that they don't fit my case:
GCD(not even sure I have it in monotouch) spawns threads on it's own whenever necessary. I need a single specific thread to schedule my work on
NSInvocationQueue(which uses GCD internally from what I read) does the same thing.
pThreads, seem overkill and managing them will be a pain(not even sure I can use them in monotouch)
I'm not an iOS developer, the app works fine with monodroid where I had Runnables and Handlers which make life easier :) . Maybe I'm not looking at this the right way and there is a simple solution to this. Any input would be appreciated.
Thanks
UPDATE
I was thinking of doing something along these lines :
Have a simple wrapper :
class SelectorHandler : NSObject
{
public static Selector Selector = new Selector("apply");
private Action execute;
public SelectorHandler(Action ex)
{
this.execute = ex;
}
[Register("apply")]
private void Execute()
{
execute();
}
}
Extend NSThread
public class Daemon : NSThread
{
public void Schedule(Action action)
{
SelectorHandler handler = new SelectorHandler(action);
handler.PerformSelector(SelectorHandler.Selector, this, null, true);
}
}
Then, when I want to call something I can do it like this :
private Daemon daemon;
public void Call_Library_With_Callback(float param, Action<int> callback)
{
daemon.Schedule(() =>
{
int callbackResult = 0;
//Native library calls
//{
// Assign callback result
//}
daemon.InvokeOnMainThread(() =>
{
callback(callbackResult);
});
});
}

What is the best way to unit test an asynchronous method?

I can't seem to find a .NET answer to this problem, which I would have thought would be fairly common.
What is the best pattern for unit testing an asynchronous method?
Obviously I need to call the method and then see if the callback fires, but is there a better way than simply sleeping for a bit and then checking for a flag that is set by the callback? Managing the flags gets a bit messy where there are multiple tests running.
I typically use an anonymous delegate and a waithandle. FOr example I have a function in my presenter called SetRemoteTableName. When the name is set, it also raises an event. I want to test that event, which is raised asynchronously. The test looks like this:
[TestMethod]
[WorkItem(244)]
[Description("Ensures calling SetRemoteTableName with a valid name works
AND raises the RemoteTableNameChange event")]
public void SetRemoteTableNamePositive()
{
string expected = "TestRemoteTableName";
string actual = string.Empty;
AutoResetEvent are = new AutoResetEvent(false);
SQLCECollectorPresenter presenter = new SQLCECollectorPresenter();
presenter.RemoteTableNameChange += new EventHandler<GenericEventArg<string>>(
delegate(object o, GenericEventArg<string> a)
{
actual = a.Value;
are.Set();
});
presenter.SetRemoteTableName(expected);
Assert.IsTrue(are.WaitOne(1000, false), "Event never fired");
Assert.AreEqual(actual, expected);
}
Split the code so that the logic is in a synchronous bit of code that is called by a thin asynchronous wrapper.
Then most of your unit tests can test the synchronous code.
is there a better way than simply sleeping for a bit and then checking for a flag that is set by the callback?
Replace the flag with a wait handle. Instead of setting the flag, set the wait handle. Instead of sleeping and then checking whether the flag is set, wait on the wait handle ... and wait with a timeout, so that if you wake up because of timer expiry instead of waking up because the handle on which you were waiting was fired by the callback, then you know that the test failed (i.e. the callback wasn't invoked within the timeout period).

Resources