Metro - write async c# operation and call from javascript - c#

I have create a metro app which is composed by
- a c# windows runtime component
- a javascript application, wich contains the UI and is the main application.
In the c# component I created an async method:
async public void createDocument() {
}
but when I try to call it from the javascript code, I cannot use the .done() or the then() function to handle the method completed evet, because there is an error: javascript error, cannot call done() from object not set to an instance of object.
If I try to assign Task or Task to the function I have another error, which tell me Task is not a windows runtime type and to use IAsyncOperation, IAsyncAction, ecc.. instead.
So, how can I create an async function in the c# windows runtime component and call it from javascript handling the done() or then() events?

I found an article that seems to be related to the problem you are having. I haven't done this myself, but the gist of it says that you can't use the async keyword from C# for Javascript promises - you must wrap the method in a slightly different way:
instead of:
public sealed class Class1
{
public async void testAsync()
{
// do this asynchronously ...
}
}
try:
public sealed class Class1
{
public IAsyncActionWithProgress<Result> testAsync()
{
return AsyncInfo.Run<Result>((token, result) =>
Task.Run<Result>(()=>
{
// do this asynchronously ...
return new Result();
}
));
}
}
public sealed class Result { ... }
}
I copied and pasted the examples from this article by Ronald Widha - http://www.ronaldwidha.net/2012/05/10/winrt-consumer-preview-calling-c-csharp-async-class-libraries-from-javascript-winjs-promises-using-then-clause/ It was written during the consumer preview, so it might have changed between then and the final release
Hopefully that will help you a bit more!

Just for information, if you need to call asyncronous methods inside the procedure, you need to use:
public static IAsyncOperation<IList<string>> DownloadAsStringsAsync(string id)
{
return Task.Run<Type retourned>(async () =>
{
var data = await AsyncMethod(...);
return (somethingOfTypeRetourned;
}).AsAsyncOperation();
}

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; }
}

How to deal with UWP async when Android and iOS are not async?

My Xamarin.Forms app has several interfaces (for Dependencys) with implementations for Android and iOS. The methods in them are not async. Now I want to add the implementations for these interfaces for UWP, but several of the needed methods are async so they don't fit the signatures. How do I deal with this? Is the only solution to create a separate interface for UWP?
In these scenarios I tend to use the Task.FromResult method for the non-async implementations. Example: you have a method on Windows that returns a Task of type bool and you want to implement the same functionality on Android and iOS for methods that return bool.
public interface ISample
{
public Task<bool> GetABool();
}
On Windows you would just return the Task
public class WindowsSample : ISample
{
public Task<bool> GetABool()
{
// whatever implementation
return SomeTaskOfTypeBool();
}
}
On Android or iOS you would wrap the value in a Task
public class AndroidSample : ISample
{
public Task<bool> GetABool()
{
// replace with however you get the value.
var ret = true;
return Task.FromResult(ret);
}
}
You can not use the await keyword. You have to create a new Task and wait for the Task to finish. A separate interface is not necessary. Exception handling with Tasks can be tricky, inform yourself.
Calling an async method Method1 with return value:
string s = Task.Run(() => Method1()).Result;
Without return value:
Task.Run(() => Method1()).Wait;
.Rest or .Wait block until the Task is completed.
More Details:
Calling async methods from non-async code

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.

How to create an awaitable class? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can constructors be async
I have a class Example that pulls several information from the internet on creation.
public class Example
{
string information;
public Example()
{
//Pull information
}
}
Now I would like to let Example become awaitable because it is important that Example is created before continuing the part after creation.
public async void SetupSomething()
{
Example ex = new Example();
await ex;
// Do something with ex
}
How can I do this?
You could do that, but I think that's not a good approach, because there is nothing forcing the await before you start using the instance.
I think a good idea would be to create static asynchronous method that creates your object. Something like:
class Example
{
private Example()
{
}
private async Task InitializeAsync()
{
// get the required data asynchronously here
}
public static async Task<Example> CreateAsync()
{
var result = new Example();
await result.InitializeAsync();
return resul;
}
}
Well, the constructor should wait until it is done doing it's stuff. After all, the thread use to create it is from the method that calls it.
However, what I think would be very important, is to show us what that constructor is doing. There's a good chance it is calling something somewhere that start another thread and doesn't wait for it to resolve, making the constructor returns while not having all the "information" you are talking about.
Might be similar to: C# : Blocking a function call until condition met

AsyncCTP: Creating a class that is IAwaitable

I found myself wanting to implement an IAwaitable class (something that implements asynchronous calls without blocking threads).
I've got the most recent version of AsyncCTP installed, and the compiler is saying that I need an IsCompleted() member. Okay, so the CTP preview has moved on a little bit (I get that, like it's a preview)
Question: What interface are the AsyncCTP language extensions expecting now?
Question: In all this I'm assuming that I can signal to the "IAwaitable" via a lamda/delegate? Is this possible? Do we call EndAwait? The intellisense suggests that you call EndAwait to retrieve the result... so that doesn't sound right. Any ideas?
All of the examples I've found so far are for features that the AsyncCTP library has already implemented such as:
await new WebClient().DownloadStringTaskAsync(uri).ConfigureAwait(false);
from the 101 AsyncSamplesCS
Background:
I find myself on Jon Skeets page (again) looking at this example
using System;
class Test
{
static async void Main()
{
await new Awaitable();
}
}
class Awaitable
{
public Awaiter GetAwaiter()
{
return new Awaiter();
}
}
class Awaiter
{
public bool BeginAwait(Action continuation)
{
return false;
}
public int EndAwait()
{
return 1;
}
}
With the SP1 refresh, you need:
Some GetAwaiter() method (possibly but not necessarily an extension method) that returns something (Awaiter in your example) with all of:
A bool IsCompleted property (get)
A void OnCompleted(Action callback)
A GetResult() method which returns void, or the desired outcome of the awaited operation
However, I suggest you look at TaskCompletionSource<T> - I looked at this, and it out-performed my naive implementation (here; obsolete). You can also use it for void tasks, by using something like a TaskCompletionSource<bool> (and exploit the fact that the Task<bool> is also an untyped Task).

Categories