This question already has answers here:
async/await - when to return a Task vs void?
(6 answers)
Closed 2 years ago.
This is my code :
class Program
{
static void Main(string[] args)
{
update();
}
static async void update()
{
await Task.Delay(100);
Console.WriteLine("X");
update();
}
}
Console never outputs any text at all, and I have no clue why. What am I doing wrong?
Your Main method is not async, so it doesn't wait for your update method. Also, your update method should return a Task so your Main method can await it.
static async Task Main(string[] args)
{
await update();
}
static async Task update()
{
await Task.Delay(100);
Console.WriteLine("X");
await update();
}
Related
I have a WPF app running on .net 6 and an external device connected to it.
Initializing the device sometimes fails and I don't want to hold the UI thread trying to initialize it.
I want to run the following method (_device.Init()) in an async fashion and when it returns true, run Start() method.
edit: run it until it returns true from the _device.Init() method, not true for finishing the task
Is there a built-in functionality to do it with tasks? or any other "best practice" way?
Thank you :)
SomeDevice _device = new();
public async void Init()
{
// some other code
while (Task.Run(() => _device.Init()).Result == false)
{
}
Start();
}
public void Start()
{
// some other code
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
_device.Start();
}));
}
Instead of getting the Result of the Task (which may block the UI thread) you should await the Task:
public async void Init()
{
// some other code
while (!await Task.Run(() => _device.Init()))
{
}
Start();
}
The method should also be awaitable and be awaited when called, e.g. in an async Loaded event handler:
public async Task Init()
{
// some other code
while (!await Task.Run(() => _device.Init()))
{
}
Start();
}
...
await Init();
public async void Init()
{
var task = _device.Init();
//do work here
await task;
Start();
}
Should do the trick, it'll do the work and then wait for the task to complete before going to Start();
If you want to simply wait for init to finish and then run start it's even simpler with
await _device.Init().ContinueWith((x) => { Start();})
I would like to know if there 'right' method to loop one task forever?
What I've tried:
private static void A()
{
Task.Run(B);
}
private static async Task B()
{
while (true)
{
Task Delay = Task.Delay(10000);
await C();
await Delay;
}
}
private static async Task C()
{
// some async code that will work every 10s
}
It is working, but I want to understand is there any better options to do the same.
Thanks in advance.
This question already has answers here:
Do you have to put Task.Run in a method to make it async?
(3 answers)
Closed 1 year ago.
When I call an async method which returns void, is it the same as when I invoke it with the Task.Run method? I ask because in the doc of the FileSystemWatcher they mention the following.
Keep your event handling code as short as possible.
https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=net-5.0#events-and-buffer-sizes
So I want to leave the scope of the event method very fast. Or do they mean something different?
Snippet of my code for better understanding.
private void OnCreated(object sender, FileSystemEventArgs e)
{
RunSaveWithLogger(AddLocation, e.FullPath);
}
private async void RunSaveWithLogger(Func<string, Task> func, string fullPath)
{
Edit:
After reading your answers and comments, I changed my code to this.
private void OnCreated(object sender, FileSystemEventArgs e)
{
Task.Run(() =>
{
RunSaveWithLogger(AddLocation, e.FullPath);
});
}
private async void RunSaveWithLogger(Func<string, Task> func, string fullPath)
{
try
{
await func.Invoke(fullPath);
}
catch (Exception exception)
{
_logger.LogError(exception, "");
}
}
Thanks for your time and help, I really appreciate that.
simple answer No! they are not the same. for instance, in the example below, "Task.Run" creates a new thread and so, runs every code within it in a new thread, while "async void" doesn't. (I doubt if this is the answer you are looking for though).
using System;
using System.Threading.Tasks;
class Solution
{
static void Main(string[] args)
{
async void Method1()
{
while (true)
{
}
}
Task.Run(() => {
while (true)
{
}
});
Console.WriteLine("This will print");
Method1();
Console.WriteLine("This won't");
}
}
This question already has answers here:
async/await - when to return a Task vs void?
(6 answers)
Closed 2 years ago.
I get OutOfMemoryException when I call this method on startup. StartSignalR method should run a Task which calls Update() method every second.
public void StartSignalR()
{
Task t = Task.Run(() =>
{
try
{
bool push = true;
while (push)
{
Update();
}
}
catch (System.Exception ex)
{
LogManager.LogError(ex);
}
});
}
I use Task.Delay in Update()
private async static void Update()
{
await Task.Delay(1000);
Updater.MPrice();
}
To make your Task.Delay actually wait, you have to declare your lambda as async and await the Update method.
public void StartSignalR()
{
//added async
Task t = Task.Run(async () =>
{
try
{
bool push = true;
while (push)
{
//await the Update method
await Update();
}
}
catch (System.Exception ex)
{
LogManager.LogError(ex);
}
});
}
With this change your Update method has to return a Task
//changed signature
private async static Task Update()
Chances are good that this should reduce the memory footprint, because currently you are firing the Update method like crazy.
I have a callback function which needs to takes several seconds to process and should be a async method, but I can't find a way to execute this async callback by await because it must be a Delegate param in the calling method.
Here is some piece of code:
async Task Callback(){//do some callback..}
async Task DoSomething(Func<Task> callback){//I want to execute the callback like: await callback();}
async void Main(){ DoSomething(Callback);}
Sorry for my poor english, any idea to do that? Thanks!
You will have to await first call itself.
change
async void Main(){ DoSomething(Callback);}
to
async void Main(){ await DoSomething(Callback);}
After that It should work, I tested with your sample code. Please verify at your end.
class Program
{
static void Main(string[] args)
{
(new Test()).Main();
Console.ReadKey();
}
}
public class Test
{
async Task Callback()
{
Console.WriteLine("I'm in callback");
}
async Task DoSomething(Func<Task> callback)
{
Console.WriteLine("I'm in DoSomething");
await callback();
}
public async void Main()
{
Console.WriteLine("I'm in Main");
await DoSomething(Callback);
Console.WriteLine("Execution completed");
}
}
Here is output