Not seeing output after using Task delay - c#

I am using an online editor for testing some C# code : https://repl.it/
I am not able to get the task after Task.Delay.
Why is this C# code not working as intended?
using System.IO;
using System;
using System.Reflection;
using System.Threading.Tasks;
class Input {
public Input() {
}
public async void hello()
{
Console.WriteLine("some task");
await Task.Delay(1000);
Console.WriteLine("after some time");
}
}
class SomeExample {
public static void Main(string[] args) {
Input std1 = new Input( );
std1.hello();
}
}

Method hello should return Task, not void. Method Main should be async Task to be able to await hello. Also you need to await std1.hello() call:
public async Task hello()
{
Console.WriteLine("some task");
await Task.Delay(1000);
Console.WriteLine("after some time");
}
public static async Task Main(string[] args)
{
Input std1 = new Input( );
await std1.hello();
}
What you have now is situation when Main method finishes its execution before hello method (because it not awaited).

Fixes: Change your method return type from void to Task. Make the console wait by adding Console.ReadLine() so that you can see the output ("after some time") and lastly, tell the method to wait and don't finish execution by adding Wait().
Hope this works.
class Input
{
public Input()
{
}
public async Task hello()
{
Console.WriteLine("some task");
await Task.Delay(1000);
Console.WriteLine("after some time");
Console.ReadLine();
}
}
class SomeExample
{
public static void Main(string[] args)
{
Input std1 = new Input();
std1.hello().Wait();
}
}

For now it seems this code is doing my work. I don't need to use async or Task keywords.
using System.IO;
using System;
using System.Threading.Tasks;
class Input
{
public Input()
{
}
public void hello()
{
Console.WriteLine("some task");
Task.Delay(1000).Wait();
Console.WriteLine("after some time");
}
}
class SomeExample
{
public static void Main(string[] args)
{
Input std1 = new Input();
std1.hello() ;
}
}

Related

C# Previous object is overwritted when adding new object to list

When I am adding new Timer to _timers it is overwriting previous one.
Console.WriteLine(_timers.Count()); is always writing 1
string.Join<string>(", ", _timers.Select(x => x.Uuid)); is returning empty string.
Here is my code:
[Group("timer")]
public class TimerHandler : ModuleBase<SocketCommandContext>
{
private List<Timer> _timers = new List<Timer>();
[Command("new")]
public async Task NewTimer(string content, [Remainder] int delay)
{
Timer timer = new Timer(content, delay, Context.Channel);
_timers.Add(timer);
Console.WriteLine(_timers.Count());
await ReplyAsync("created new timer with id: " + timer.Uuid);
}
[Command("list")]
public async Task ListTimer()
{
string reply;
string reply = string.Join<string>(", ", _timers.Select(x => x.Uuid));
await ReplyAsync(reply);
}
}
At times like these, what I try to do is create a minimum reproducible sample that removes anything unrelated to the problem. You could use a quick console app like I did here or a Unit Test. What this seems to show is that your code works as far as is shown:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
namespace timer_list
{
class Program
{
static void Main(string[] args)
{
runAsync();
Console.ReadKey();
}
static async void runAsync()
{
var timerHandler = new TimerHandler();
for (int i = 0; i < 5; i++)
{
await timerHandler.NewTimer("unused");
}
}
public class TimerHandler // : ModuleBase<SocketCommandContext>
{
private List<Timer> _timers = new List<Timer>();
public async Task NewTimer(string content)
{
Timer timer = new Timer();
_timers.Add(timer);
Console.WriteLine(_timers.Count());
await Task.Delay(1);
}
public async Task ListTimer()
{
await Task.Delay(10);
}
}
}
}
This makes me wonder if you're making a new instance of TimerHandler every time you use it. If this is the case, try changing:
private List<Timer> _timers = new List<Timer>()
to
private static List<Timer> _timers = new List<Timer>()
and see if that helps!

How to call multiple methods parallelly by using async programming in C#

public class Program
{
public static void Main(string[] args)
{
Start();
Console.ReadLine();
}
private static async Task Start()
{
var m1 = method1();
var m2 = method2();
await Task.WhenAll(m1, m2);
}
private static async Task method1()
{
Console.WriteLine("Method1 - Start");
Thread.Sleep(1000);
Console.WriteLine("Method1 - End");
}
private static async Task method2()
{
Console.WriteLine("Method2 - Start");
Thread.Sleep(1000);
Console.WriteLine("Method2 - End");
}
}
The above code returning below out
Method1 - Start
Method1 - End
Method2 - Start
Method2 - End
I want an output like
Method1 - Start
Method2 - Start
Method1 - End
Method2 - End
how to achieve that basically how to run async methods in parallel
Option A - with Task.Delay
public class Program
{
public static async Task Main()
{
await Start();
Console.ReadLine();
}
private static async Task Start()
{
var m1 = method1();
var m2 = method2();
await Task.WhenAll(m1, m2);
}
private static async Task method1()
{
Console.WriteLine("Method1 - Start");
await Task.Delay(1000);
Console.WriteLine("Method1 - End");
}
private static async Task method2()
{
Console.WriteLine("Method2 - Start");
await Task.Delay(1000);
Console.WriteLine("Method2 - End");
}
}
Option B - with Task.Run
public class Program
{
public static async Task Main()
{
await Start();
Console.ReadLine();
}
private static async Task Start()
{
var m1 = Task.Run(() => method1());
var m2 = Task.Run(() => method2());
await Task.WhenAll(m1, m2);
}
private static void method1()
{
Console.WriteLine("Method1 - Start");
Thread.Sleep(1000);
Console.WriteLine("Method1 - End");
}
private static void method2()
{
Console.WriteLine("Method2 - Start");
Thread.Sleep(1000);
Console.WriteLine("Method2 - End");
}
}
Or you can use Task.Yield().
public class Program
{
public static void Main(string[] args)
{
Start();
Console.ReadLine();
}
private static async Task Start()
{
var m1 = method1();
var m2 = method2();
await Task.WhenAll(m1, m2);
}
private static async Task method1()
{
await Task.Yield();
Console.WriteLine("Method1 - Start");
Thread.Sleep(1000);
Console.WriteLine("Method1 - End");
}
private static async Task method2()
{
await Task.Yield();
Console.WriteLine("Method2 - Start");
Thread.Sleep(1000);
Console.WriteLine("Method2 - End");
}
}
This one is a bit "more parallel" than using Task.Delay() because it immediately yields back an uncomplete task, but with delay the "asynchronicity" only happens when you reach that line of code. If you have long running sync code before the delay, that will delay the execution of subsequent methods (in this case method2).
Edit
a more detailed explanation on When would I use Task.Yield()?

How make method start new execution only when finished previous execution

Hello How make method MethodA start new execution only when finished previous execution?
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
MethodB();
MethodC();
}
public static void MethodA ()
{
Console.WriteLine("Start");
Thread.Sleep(200);
Console.WriteLine("Stop");
}
public static void MethodB()
{
Task.Run(() => MethodA());
}
public static void MethodC()
{
Task.Run(() => MethodA());
}
}
In this case I have this result
Hello World
Start
Start
Stop
Stop
But I need something like this
Hello World
Start
Stop
Start
Stop
The simplest way is to create a static locking object and reference that in MethodA:
private static readonly object _methodALockObject = new object();
public static void MethodA()
{
lock(_methodALockObject)
{
Console.WriteLine("Start");
Thread.Sleep(200);
Console.WriteLine("Stop");
}
}
Try to use async and await:
public static void Main()
{
Task.Run(async () =>
{
await MethodB();
await MethodC();
}).GetAwaiter().GetResult();
}
public static void MethodA()
{
Console.WriteLine("Start");
Thread.Sleep(200);
Console.WriteLine("Stop");
}
public async static Task MethodB()
{
await Task.Run(() => MethodA());
}
public async static Task MethodC()
{
await Task.Run(() => MethodA());
}
async and await keywords help to make your asynchronous code to be executed in syncronous order.

Starting a task using delegate in C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TaskStart
{
class Program
{
private static void PrintMessage()
{
Console.WriteLine("Hello Task library!");
}
static void Main(string[] args)
{
//method 1
//Task.Factory.StartNew(() => { Console.WriteLine("Hello Task library!");});
//method 2
//Task task = new Task(new Action(PrintMessage));
//task.Start();
//method3
Task task = new Task(delegate { PrintMessage(); });
task.Start();
}
}
}
I am trying to get my Console app to print the message Hello Task library!. I am currently using method 3 below. For some reason the app shows a blank screen with the message Press any key to continue when I press Ctrl + F5 on VS2015.
Why is my message not getting printed.
This is because you are not waiting for your task to complete. Try add task.Wait() to the end of your method and see the result should be displayed.
Update: If you are using Visual Studio 2017 Update 15.3 or above and C# 7.1, there is support for async Main now.
You can modify your code as follows:
class Program
{
private static void PrintMessage()
{
Console.WriteLine("Hello Task library!");
}
static async Task Main()
{
var task = new Task(PrintMessage);
task.Start();
await task;
}
}

The simplest possible infinitely repeat

I need the simplest possible Timer to repeat my code infinitely every 5 seconds. No external classes or whatnot.
Just:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Now the following code will be repeated over and over");
//////////////// FOLLOWING CODE /////////////////
/* the repeated code */
//////////////// END OF FOLLOWING CODE /////////////////
}
}
How can I do that?
Use while(true) with Thread.Sleep
using System.Threading;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Now the following code will be repeated over and over");
while(true)
{
//////////////// FOLLOWING CODE /////////////////
/* the repeated code */
//////////////// END OF FOLLOWING CODE /////////////////
Thread.Sleep(5000);
}
}
}
Simplest form of it :
using System.Threading;
static void Main(string[] args)
{
bool breakConditionFlag = false;
ManualResetEvent waitHandler = new ManualResetEvent(false);
while(breakConditionFlag)
{
//Your Code
waitHandler.WaitOne(TimeSpan.FromMilliseconds(1000)); // 1000 is the Arbitary value you can change it to Suit your purpose;
}
}
Why ManualResetEvent ?
The event makes more efficient use of the processors- you're not having to wake the parent thread up to poll. The kernel will wake you up when the event fires.
Use Timer.
static void Main(string[] args)
{
Timer timer = new System.Threading.Timer((e) =>
{
Console.WriteLine("Now the following code will be repeated over and over");
}, null, 0, (int)TimeSpan.FromSeconds(5).TotalMilliseconds);
Console.Read();
}
Here I have called Console.WriteLine multiple times, you can write your code block instead of it.
You can use Thread.Sleep(5000); But again its also external class according to the OP.
But I would suggest a better solution using Async and Await. One more thing you should have a termination condition, so that you dont produce an infinite call to avoid unnecessary memory consumption.
public static async Task RepeatActionEveryInterval(Action action, TimeSpan interval, CancellationToken cancelToken)
{
while (true)
{
action();
Task task = Task.Delay(interval, cancelToken);
try
{
await task;
}
catch (TaskCanceledException)
{
return;
}
}
}
static void Main(string[] args)
{
CancellationTokenSource cancelToken = new CancellationTokenSource(TimeSpan.FromSeconds(50));
Console.WriteLine("Start");
RepeatActionEveryInterval(() => Console.WriteLine("Repeating Code"), TimeSpan.FromSeconds(5), cancelToken.Token).Wait();
Console.WriteLine("End");
Console.Read();
}
In this example this code will write till 50 seconds.
Use this code for call your function recursively for every 5 seconds.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace recurssiveWithThread
{
class Program
{
static void Main(string[] args)
{
RecWork();
}
public static int i = 0;
public static void RecWork()
{
// Do the things whatever you needed here
i++;
Console.WriteLine(i);
//Thread to make the process to sleep for sometimes
Thread.Sleep(5000);
//Call your function here
RecWork();
}
}
}
Use BackgroundWorker class:
Reference links:
Background worker
If you are using framework >= 4.5.2 QueueBackgroundWorkItem
QueueBackgroundWorkItem

Categories