await Task using reflection in .Net for Store apps [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
There is a method which will take a Task as input and await.
protected async Task DoTask(Task t)
{
//Do something
await t;
}
The second method will accept the method name in string format and will create the method object using Reflection. Task needs to be created instead of invoking it and pass it to first method
This two methods are part of a base class . The child class which is a view model will call DoTask2 and pass the name of the function defined inside itself(i.e.view model).
protected async Task DoTask2(string method)
{Task t = null;
var typeInfo = this.GetType().GetTypeInfo();
var methods = typeInfo.DeclaredMethods;
var meth = methods .Single(o => String.Equals(o.Name, method));
t = meth .Invoke(this, null) as Task;
await DoTask(t);
}
But this is not working properly. Is something wrong here in the approach.
I am trying to build this in a windows 8.1 store app
EDIT:
Upon executing this line, instead getting the Task object, the async method is getting invoked. I need to get the task so that I can pass it to the next method.
.
I want to get the method using reflection but create it as a new Task execute using my doTask method. All methods are in the same class. Dotask and Dotask2 are in the base class.

I think the main problem here is one of expectation;
I want to get the method using reflection but create it as a new Task execute using my doTask method.
That simply isn't how most async APIs work; invoking an async method: is executing an async method - or more specifically, it is executing the method as far as the first continuation that reports as incomplete. Invoking an async method does not just create an as-yet unstarted token to a method. I wonder if you might actually want a Func<Task> rather than a Task - a Func<Task> is a delegate that returns a Task when invoked - but without invoking it yet. There are ways to create a Func<T> directly from a MethodInfo in regular .NET, but in windows-store apps you might need to be indirect:
Func<Task> invoker = () => (Task)meth.Invoke(this, null);
You would then have:
private async Task DoTask(Func<Task> invoker)
{
var t = invoker(); //Do something code goes somewhere in this method
await t;
}

Related

How to wrap a synchronous function to async function in C#? [duplicate]

This question already has an answer here:
Awaiting a Callback method
(1 answer)
Closed 1 year ago.
am using a synchronous 3rd function which I cannot modify, such as:
public void startDoSth(Action<string> onDone)
startDoSth spawn a new thread to do the job, and returns immediately, and when the thing is done, my onDone function would be called.
I'd like to write an asynchronous method like below to wrap it:
public async Task<string> doSthAsync();
So, someone can call it like this:
string s = await doSthAsync()
onDone(s)
In doSthasync() I call startDoSth() to do the real thing.
But I have no idea how to write the doSthAsync().
Could anyone tell if it is possible and how to do it? Thanks a lot.
You can use TaskCompletionSource to convert that into TAP:
Task<string> DoSthAsync()
{
var tcs = new TaskCompletionSource<string>();
startDoSth(tcs.SetResult);
return tcs.Task;
}
SetResult completes the returned Task (and sets the result), so that can be passed as the callback function.

Multi Threading in API in C# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm trying to create an Web Service that runs an asynchronous function with .Net Core Framework.
This function must be executed in its own thread and return a new value that will be sent to the proper caller.
The service must be listening for other calls while my async function is running, and start a new thread for each call.
Once the thread is finished, I want the response to be sent to the original caller.
I have tried this way :
In my controller I have :
[Route("api/orchestration")]
public class OrchController : Controller
{
[HttpGet("{value}")]
public void RunOrchestration(int value)
{
Program.GetResultAsync(value); // Notice that no value is returned but it respects the asynchronicity and the multithreading as asked
}
}
In my main class I have :
public async static Task<string> GetResultAsync(int i)
{
return await OrchestrationAsync(i);
}
public static Task<string> OrchestrationAsync(int i)
{
return Task.Run<string>(() => { return r = Orchestration(i); });
}
public static string Orchestration(Object i)
{
// This function is an orchestrator of microservices that talk asynchronously through a MOM
// Just consider that it returns the value I want in a string
return result;
}
As you can see I want my function GetResultAsync to return a string with the value that will be sent to the caller.
Yet I can't have something like this (see code below) because GetResultAsync returns a Task and not a string :
public string RunOrchestration(int value)
{
return r = Program.GetResultAsync(value);
}
And if I put an await in RunOrchestration, it will wait for the response and will behave as a synchronous function.
Anyone has an idea on how to get my response and give it back to the proper caller ?
Thank's in advance ! :)
I wish I could just somehow broadcast at once to every .NET developer in the world: async is not multithreading/parallel processing/background processing, etc.
Async does one and only one thing: it allows the current thread to be returned to the pool if it's idle. That's it. Period. End of story. If you're doing something like creating a new thread, that effectively idles the original thread allowing it to be returned to the pool, but you still have a thread. In other words, you did absolutely nothing but add a bunch of overhead and context switching to your code, making it less efficient, not more.
What you need here is a true background process. You can use something like Hangfire to fire off a task, and then that task can be handled by something. That could be a console app, another web application, an Azure Function, whatever. The point is that it's external to your main web application. Then, you can immediately return, without waiting for that thing, whatever it is, to finish. You can, also, utilize something like SignalR and web workers to push status updates to the client.
Of course, the return value of GetResultAsync is Task (not a string) This is exactly what it should be. You probably misunderstood the concept of await/async. if you want string - you should call
await Program.GetResultAsync(value)
Read this topic :
How and When to use `async` and `await`
Nevertheless, such construction is futile. You are not gaining anything by async/await here.

async library calls relying on each other and how to handle?

this is a follow on from a previous question I posted Calling an async method using a Task.Run seems wrong?
I thought the code written by the contractor was wrong but following on from the answers provided I'm now wondering if it's the libraries fault. This library exposes two methods that I need to use. One returns a "template" and one consumes part of this template (it does in my implementation anyway). But both are async methods returning Tasks.
To explain my library has methods:
public Task<TemplateInfo> TemplateInfo(TemplateInfoRequest request);
public Task<List<EmailResult>> SendMessageTemplate(SendMessageTemplateRequest request);
I need to call these thus:
public bool SendMessage()
{
var template = TemplateInfo(...);
var message = //use template to create message
var sendResponse = SendMessageTemplate(message);
return sendResponse.Count > 0;
}
So the second call relies on the first. This is where the async doesn't make sense to me. I can't and don't want to run these in parallel. I want to run them in sequence. I want my method to by synchonous.
An answer in my previous question also states:
Since you're blocking on an async method (which you shouldn't do)
there is a chance you'll deadlock.
So how do I access these async methods in such a way that they are processed in turn and return a synconhonous result but do not cause deadlocks?
Async doesn't (necessarily) means parallel.
You can call both async method sequentially without them running in parallel. Simply call the first and await the returned task and then do the same with the second.
var template = await TemplateInfo(...);
var message = //use template to create message
var sendResponse = await SendMessageTemplate(message);
This is still useful compared to synchronous code because while the asynchronous operation is "running" there's no thread needed and so your threads can go work on other parts of your application.
If you would call both and only then await the returned tasks you will (maybe) run in parallel:
var templateTask = TemplateInfo(...);
var sendResponseTask = SendMessageTemplate(message);
await templateTask;
await sendResponseTask;

Await operator can only be used within an Async method [duplicate]

This question already has answers here:
Can't specify the 'async' modifier on the 'Main' method of a console app
(20 answers)
Closed 5 years ago.
I'm trying to make a simple program to test the new .NET async functionality within Visual Studio 2012. I generally use BackgroundWorkers to run time-consuming code asynchronously, but sometimes it seems like a hassle for a relatively simple (but expensive) operation. The new async modifier looks like it would be great to use, but unfortunately I just can't seem to get a simple test going.
Here's my code, in a C# console application:
static void Main(string[] args)
{
string MarsResponse = await QueryRover();
Console.WriteLine("Waiting for response from Mars...");
Console.WriteLine(MarsResponse);
Console.Read();
}
public static async Task<string> QueryRover()
{
await Task.Delay(5000);
return "Doin' good!";
}
I checked out some examples on MSDN and it looks to me like this code should be working, but instead I'm getting a build error on the line containing "await QueryRover();" Am I going crazy or is something fishy happening?
You can only use await in an async method, and Main cannot be async.
You'll have to use your own async-compatible context, call Wait on the returned Task in the Main method, or just ignore the returned Task and just block on the call to Read. Note that Wait will wrap any exceptions in an AggregateException.
If you want a good intro, see my async/await intro post.

Is it possible to use same async method signature in C# 5.0 and be able to decide later how to execute such method

I want to use recent C# 5.0 async methods, however some specific way.
Consider following example code:
public abstract class SomeBaseProvider : ISomeProvider
{
public abstract Task<string> Process(SomeParameters parameters);
}
public class SomeConcreteProvider1 : SomeBaseProvider
{
// in this method I want to minimize any overhead to create / run Task
// NOTE: I remove here async from method signature, because basically I want to run
// method to run in sync!
public override Task<string> Process(SomeParameters parameters) {
string result = "string which I don't need any async code to get";
return Task.Run(() => result);
}
}
public class SomeConcreteProvider2 : SomeBaseProvider
{
// in this method, it's OK for me to use async / await
public async override Task<string> Process(SomeParameters parameters) {
var data = await new WebClient().DownloadDataTaskAsync(urlToRequest);
string result = // ... here we convert data byte[] to string some way
return result;
}
}
Now how I am going to use async methods (you can ignore fact that consumer actually ASP.NET MVC4 app in my case... it can be anything):
public class SomeAsyncController : AsyncController
{
public async Task<ActionResult> SomethingAsync(string providerId)
{
// we just get here one of providers I define above
var provider = SomeService.GetProvider(providerId);
// we try to execute here Process method in async.
// However we might want to actually do it in sync instead, if
// provider is actually SomeConcreteProvider1 object.
string result = await provider.Process(new SomeParameters(...));
return Content(result);
}
}
As you can see I have 2 implementations, each one will perform differently: one I want to run in async and do not block thread (SomeConcreteProvider2), while another one I want to be able to run in sync and do not create any Task object etc (which I fail to code in code above, i.e. I do create new Task here!).
There are questions already like How would I run an async Task<T> method synchronously?. However I don't want to run something in sync... I want to avoid any overhead if I know at code time (i.e. before runtime) that some methods implementations will NOT actually be async and will not need to use any threads / I/O completion ports etc. If you check code above, its easy to see that method in SomeConcreteProvider1 basically will construct some string (html), can do it very quickly at the same execution thread. However same method in SomeConcreteProvider2 will need to create Web Request, get Web Response and process it someway and I do want to make at least Web Request in Async to avoid blocking of whole thread during request time (may be quit long time actually).
So the question is: how to organize my code (different method signatures or different implementations, or?) to be able to decide how to execute method and avoid ANY possible overhead which caused for example by Task.Run(...) in SomeConcreteProvider1.Process method?
Update 1: obvious solutions (I think up some of them during question process), such as for example to add some static property to each of providers (say 'isAsyncImplementation') and then check that property to decide how to run method (with await or without await in controller action) have some overhead too :D I want something better if possible :D
In your first case, I would recommend returning:
Task.FromResult(result)
which returns a ready-completed task.
http://msdn.microsoft.com/en-us/library/hh194922%28v=vs.110%29.aspx
Your design looks fine.
For the SomeConcreteProvider1 case, you can use a TaskCompletionSource
This returns a Task without requiring concurrency.
Also, in the consumer code, await will not yield if the Task has already completed. This is called the "fast path" and effectively makes the method synchronous.

Categories