Async function does not return control to the main thread (linq expression) - multithreading

I thought that I got threads in .NET, but when I have added LINQ expression it made me a little confused.
Like I wrote in the topic of this discussion I dont why the thread doesnt return control to the main action of my controller.
I have written what makes me silly in comments, so let me skip to the true example:
public class ValuesController : ApiController
{
public async Task<List<SomeProduct>> Get()
{
var collection = new List<Mother>() {
new Mother()
{
internalField = new List<Child>()
{
new Child()
{
theLastOne = "VAL"
},
new Child()
{
theLastOne = "VAL"
}
}
}
};
var oss =
from m in collection
from s in m.internalField
select Convert(m, s).Result;
//1-The above code doesnt enter into CONVERT function (I have a breakpoint there)
return oss.ToList();//2- this list enter into COnvertt
}
private async Task<SomeProduct> Convert(Mother ms, Child ss)
{
var ossNEW = new SomeProduct();
await update(ossNEW, ms);
return ossNEW;
}
private async Task update(SomeProduct oss, Mother ms)
{//3 - Naturally it comes here
await Task.Run(()=>
{
//This task is executed (It is example code, pls do not care, that threads do not have any sense
oss.copyOfTheLastOne = ms.internalField.First().theLastOne;
oss.valeFromAnUpdateFunction = "works";
}); //Flow comes here and THIS line does not return control to the main action, why? :)
}
}
public class SomeProduct
{
public string copyOfTheLastOne;
public string valeFromAnUpdateFunction;
}
public class Mother
{
public List<Child> internalField;
}
public class Child
{
public string theLastOne;
}
I have solved this example by adding an "executor", which takes list of the tasks and manage it.
public class ValuesController : ApiController
{
public async Task<List<SomeProduct>> Get()
{
var collection = new List<Mother>() {
new Mother()
{
internalField = new List<Child>()
{
new Child()
{
theLastOne = "VAL"
},
new Child()
{
theLastOne = "VAL"
}
}
}
};
var oss =
from m in collection
from s in m.internalField
select Convert(m, s);
List<Task<SomeProduct>> downloadTasks = oss.ToList();
List<SomeProduct> ossNew = new List<SomeProduct>();
while (downloadTasks.Count > 0)
{
var firstFinishedTask = await Task.WhenAny(downloadTasks);
downloadTasks.Remove(firstFinishedTask);
ossNew.Add(await firstFinishedTask);
}
return ossNew;
}
private async Task<SomeProduct> Convert(Mother ms, Child ss)
{
var ossNEW = new SomeProduct();
await update(ossNEW, ms);
return ossNEW;
}
private async Task update(SomeProduct oss, Mother ms)
{
await Task.Run(()=>
{
oss.copyOfTheLastOne = ms.internalField.First().theLastOne;
oss.valeFromAnUpdateFunction = "works";
});
}
To fully understand the problem, I would like to know why the UPDATE function does not return control to the main action and why RESULT on CONVERT function does not force to run program synchronously?

I would like to know why the UPDATE function does not return control to the main action and why RESULT on CONVERT function does not force to run program synchronously?
You're running into a common deadlock problem that I explain in full on my blog, due to the use of Result. Use await instead of Result and your problem goes away (in your case, since you have a collection, you'll want to await Task.WhenAll):
public async Task<SomeProduct[]> Get()
{
var collection = new List<Mother>() {
new Mother()
{
internalField = new List<Child>()
{
new Child()
{
theLastOne = "VAL"
},
new Child()
{
theLastOne = "VAL"
}
}
}
};
var oss =
from m in collection
from s in m.internalField
select Convert(m, s);
return Task.WhenAll(oss);
}
On a side note, you shouldn't use Task.Run in your implementations, particularly on ASP.NET. On ASP.NET, Task.Run completely removes all the benefits of async and adds overhead.

Related

Could haxe macro be used to detect when object is dirty (any property has been changed)

Let say we have an object:
#:checkDirty
class Test {
var a:Int;
var b(default, default):String;
var c(get, set):Array<Int>;
public function new() {
...
}
public function get_c() {
...
}
public function set_c(n) {
...
}
}
Could we write a macro checkDirty so that any change to field/properties would set property dirty to true. Macro would generate dirty field as Bool and clearDirty function to set it to false.
var test = new Test();
trace(test.dirty); // false
test.a = 12;
trace(test.dirty); // true
test.clearDirty();
trace(test.dirty); //false
test.b = "test"
trace(test.dirty); //true
test.clearDirty();
test.c = [1,2,3];
trace(test.dirty); //true
Just to note - whenever you consider proxying access to an object, in my experience, there are always hidden costs / added complexity. :)
That said, you have a few approaches:
First, if you want it to be pure Haxe, then either a macro or an abstract can get the job done. Either way, you're effectively transforming every property access into a function call that sets the value and also sets dirty.
For example, an abstract using the #:resolve getter and setter can be found in the NME source code, replicated here for convenience:
#:forward(decode,toString)
abstract URLVariables(URLVariablesBase)
{
public function new(?inEncoded:String)
{
this = new URLVariablesBase(inEncoded);
}
#:resolve
public function set(name:String, value:String) : String
{
return this.set(name,value);
}
#:resolve
public function get(name:String):String
{
return this.get(name);
}
}
This may be an older syntax, I'm not sure... also look at the operator overloading examples on the Haxe manual:
#:op(a.b) public function fieldRead(name:String)
return this.indexOf(name);
#:op(a.b) public function fieldWrite(name:String, value:String)
return this.split(name).join(value);
Second, I'd just point out that if the underlying language / runtime supports some kind of Proxy object (e.g. JavaScript Proxy), and macro / abstract isn't working as expected, then you could build your functionality on top of that.
I wrote a post (archive) about doing this kind of thing (except for emitting events) before - you can use a #:build macro to modify class members, be it appending an extra assignment into setter or replacing the field with a property.
So a modified version might look like so:
class Macro {
public static macro function build():Array<Field> {
var fields = Context.getBuildFields();
for (field in fields.copy()) { // (copy fields so that we don't go over freshly added ones)
switch (field.kind) {
case FVar(fieldType, fieldExpr), FProp("default", "default", fieldType, fieldExpr):
var fieldName = field.name;
if (fieldName == "dirty") continue;
var setterName = "set_" + fieldName;
var tmp_class = macro class {
public var $fieldName(default, set):$fieldType = $fieldExpr;
public function $setterName(v:$fieldType):$fieldType {
$i{fieldName} = v;
this.dirty = true;
return v;
}
};
for (mcf in tmp_class.fields) fields.push(mcf);
fields.remove(field);
case FProp(_, "set", t, e):
var setter = Lambda.find(fields, (f) -> f.name == "set_" + field.name);
if (setter == null) continue;
switch (setter.kind) {
case FFun(f):
f.expr = macro { dirty = true; ${f.expr}; };
default:
}
default:
}
}
if (Lambda.find(fields, (f) -> f.name == "dirty") == null) fields.push((macro class {
public var dirty:Bool = false;
}).fields[0]);
return fields;
}
}
which, if used as
#:build(Macro.build())
#:keep class Some {
public function new() {}
public var one:Int;
public var two(default, set):String;
function set_two(v:String):String {
two = v;
return v;
}
}
Would emit the following JS:
var Some = function() {
this.dirty = false;
};
Some.prototype = {
set_two: function(v) {
this.dirty = true;
this.two = v;
return v;
}
,set_one: function(v) {
this.one = v;
this.dirty = true;
return v;
}
};

Cannot call function in the same class

I defined a class called Plan. Here is the code:
class Plan {
async getPlanText(ctx) {
return await this.getPlanDetails(ctx);
}
async getPlanDetails(ctx) {
return ...
}
}
exports.Plan = Plan;
I get:
this.getPlanDetails is not a function
What I did wrong?
I used the Plan class in this way:
const { Plan } = require('./controllers/plan.controller');
let planController = new Plan();
console.log(planController.getPlanText('my context'));
try this. Basically you need to bind the function to a class while passing so it knows where to get the dependencies from. You can read more here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
const planController = new Plan();
const menu = new TelegraphInlineMenu(planController.getPlanText.bind(planController))

passing function to a class in nodejs

I have a function that I need to pass to a class I have defined in nodeJs.
The use case scenario is I want to give the implementer of the class the control of what to do with the data received from createCall function. I don't mind if the method becomes a member function of the class. Any help would be appreciated.
//Function to pass. Defined by the person using the class in their project.
var someFunction = function(data){
console.log(data)
}
//And I have a class i.e. the library.
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall(){
var result = new Promise (function(resolve,reject) {
resolve(callApi());
});
//doesn't work. Keeps saying notificationHandler is not a function
result.then(function(resp) {
this.notificationHandler(resp);
}) ;
//I want to pass this resp back to the function I had passed in the
// constructor.
//How do I achieve this.
}
callApi(){ ...somecode... }
}
// The user creates an object of the class like this
var obj = new A("abc#gmail.com", someFunction);
obj.createCall(); // This call should execute the logic inside someFunction after the resp is received.
Arrow functions (if your Node version supports them) are convenient here:
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall() {
var result = new Promise(resolve => {
// we're fine here, `this` is the current A instance
resolve(this.callApi());
});
result.then(resp => {
this.notificationHandler(resp);
});
}
callApi() {
// Some code here...
}
}
Inside arrow functions, this refers to the context that defined such functions, in our case the current instance of A. The old school way (ECMA 5) would be:
createCall() {
// save current instance in a variable for further use
// inside callback functions
var self = this;
var result = new Promise(function(resolve) {
// here `this` is completely irrelevant;
// we need to use `self`
resolve(self.callApi());
});
result.then(function(resp) {
self.notificationHandler(resp);
});
}
Check here for details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

Making an asynchronous function synchronous for the Node.js REPL

I have a library that connects to a remote API:
class Client(access_token) {
void put(key, value, callback);
void get(key, callback);
}
I want to set up a Node.js REPL to make it easy to try things out:
var repl = require('repl');
var r = repl.start('> ');
r.context.client = new Client(...);
The problem is that an asynchronous API is not convenient for a REPL. I'd prefer a synchronous one that yields the result via the return value and signals an error with an exception. Something like:
class ReplClient(access_token) {
void put(key, value); // throws NetworkError
string get(key); // throws NetworkError
}
Is there a way to implement ReplClient using Client? I'd prefer to avoid any dependencies other than the standard Node.js packages.
You can synchronously wait for stuff with the magic of wait-for-stuff.
Based on your example specification:
const wait = require('wait-for-stuff')
class ReplClient {
constructor(access_token) {
this.client = new Client(access_token)
}
put(key, value) {
return checkErr(wait.for.promise(this.client.put(key, value)))
}
get(key) {
return checkErr(wait.for.promise(this.client.get(key)))
}
}
const checkErr = (maybeErr) => {
if (maybeErr instanceof Error) {
throw maybeErr
} else {
return maybeErr
}
}

Construct Task from WaitHandle.Wait

I chose to return Task<T> and Task from my objects methods to provide easy consumation by the gui. Some of the methods simply wait for mutex of other kind of waithandles . Is there a way to construct Task from WaitHandle.Wait() so that I don't have to block one treadpool thread for that.
There is a way to do this: you can subscribe to WaitHandle using ThreadPool.RegisterWaitForSingleObject method and wrap it via TaskCompletionSource class:
public static class WaitHandleEx
{
public static Task ToTask(this WaitHandle waitHandle)
{
var tcs = new TaskCompletionSource<object>();
// Registering callback to wait till WaitHandle changes its state
ThreadPool.RegisterWaitForSingleObject(
waitObject: waitHandle,
callBack:(o, timeout) => { tcs.SetResult(null); },
state: null,
timeout: TimeSpan.MaxValue,
executeOnlyOnce: true);
return tcs.Task;
}
}
Usage:
WaitHandle wh = new AutoResetEvent(true);
var task = wh.ToTask();
task.Wait();
As noted by #gordy in the comments of the accepted answer of Sergey Teplyakov, MSDN proposes an implementation with unsubscription of the registered WaitHandle.
I slightly modified it here to support the result of the callback: if the registration has timed out, the task return false. If the signal has been received, the task return true:
public static class ExtensionMethods
{
public static Task<bool> WaitOneAsync(this WaitHandle waitHandle, int timeoutMs)
{
if (waitHandle == null)
throw new ArgumentNullException(nameof(waitHandle));
var tcs = new TaskCompletionSource<bool>();
RegisteredWaitHandle registeredWaitHandle = ThreadPool.RegisterWaitForSingleObject(
waitHandle,
callBack: (state, timedOut) => { tcs.TrySetResult(!timedOut); },
state: null,
millisecondsTimeOutInterval: timeoutMs,
executeOnlyOnce: true);
return tcs.Task.ContinueWith((antecedent) =>
{
registeredWaitHandle.Unregister(waitObject: null);
try
{
return antecedent.Result;
}
catch
{
return false;
}
});
}
}
Usage is same as the original answer:
WaitHandle signal = new AutoResetEvent(initialState: false);
bool signaled = await signal.WaitOneAsync(1000);
if (signaled)
{
Console.WriteLine("Signal received");
}
else
{
Console.WriteLine("Waiting signal timed out");
}

Resources