If I have a given method, for example:
protected Task CreateItemsAsync(object source)
{
return Task.Factory.StartNew(() =>
{
///////
code
///////
}
}
I have a bunch of code in the method but I cannot step into the method. Is there a way to proceed step by step in the code?
Try this code in a Console app:
using System;
using System.Threading.Tasks;
namespace Demo
{
public static class Program
{
[STAThread]
private static void Main()
{
var task = test();
Console.WriteLine(task.Result);
}
private static Task<int> test()
{
return Task<int>.Factory.StartNew(() =>
{
int x = 10; // <-- Set a breakpoint here.
int y = 5;
int z = x/y;
return z;
});
}
}
}
Set a breakpoint at the indicated line, and then debug the program.
The debugger will stop at the indicated line, and you will be able to single-step through the rest of the lines in the thread.
Related
This question already has an answer here:
async Task vs async void
(1 answer)
Closed 3 years ago.
How would I make the main thread wait until DisplayAdd has displayed the output? If I add a Console.Read() at the end, everything works but is there another way to tell the main thread to wait until Calculate() has finished?
namespace TestDelegate
{
public class Add
{
public delegate void SendResult(int i);
public SendResult WhereToSend;
public async void Calculate (int number)
{
Console.WriteLine("Entered");
int result = number + number;
await Task.Delay(4000);
WhereToSend (result);
// Console.Read();
}
}
}
namespace TestStuff
{
class Program
{
static void Main(string[] args)
{
Add obj = new Add();
Console.WriteLine("Started Calculating");
obj.Calculate(10);
obj.WhereToSend = DisplayAdd;
}
static void DisplayAdd(int value)
{
Console.WriteLine(value);
}
}
}
You can define the delegate as Task return type (awaitable type). With this the method will finish before main thread terminates.
namespace TestDelegate
{
public delegate Task SendResult(int i);
public class Add
{
public SendResult WhereToSend;
public async Task Calculate (int number)
{
Console.WriteLine("Entered");
int result = number + number;
await WhereToSend (result);
}
}
}
namespace TestStuff
{
class Program
{
static void Main(string[] args)
{
Add obj = new Add();
obj.WhereToSend = DisplayAdd;
Console.WriteLine("Started Calculating");
obj.Calculate(10).Wait();
}
static async Task DisplayAdd(int value)
{
// Some awaitable operation like below as per your business logic
await Task.Delay(1);
Console.WriteLine(value);
}
}
}
In above program, I've changed the definition of Calculate method to async Task so that it can be marked for Waitable. The async void method are primarily used for UI events hanlder or fire and forget method.
Please check this dotnetfiddle which demonstrates the scenario.
I am a bit confused about calling recursive method from itself.
Here is a sample code:
class Program
{
public static void main(String args[])
{
Program p = new Program();
p.Foo();
}
Public ... Foo()
{
Foo();
}
Do i need to create new instance of Program to call Foo from Foo?
My code works without the instance but I am not sure if its correct.
Thanks
You don't need to make a new instance of Program, but onlu of you declare your Foo method as static. If you keep it as it is, you will need to make a new instance of Program, which I suggest you not to, because it is not a good practice to have a class which instantiate itself in a static method, only to call a nonstatic method. You should have:
class Program
{
public static void main(String args[])
{
Foo(); //direct call to Foo
}
public static ... Foo()
{
Foo();
}
}
No, you do not have to create a new class. Here is an (unittest) example.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
namespace UnitTestProject
{
[TestClass]
public class UnitTest
{
public class Factorial
{
Dictionary<int, long> store = new Dictionary<int, long>();
public long Get(int number)
{
if (store.ContainsKey(number))
{
return store[number];
}
if (number == 0)
{
store.Add(0, 1);
return 1;
}
var result = number * Get(number - 1);
store.Add(number, result);
return result;
}
}
[TestMethod]
public void SomeTest()
{
// Arrange
var target = new Factorial();
var results = new List<long>();
// Act
for (int i = 10; i >= 0; i--)
{
results.Add(target.Get(i));
}
// Assert
}
}
}
The requirement is to call a method after every 12 hours. The code below the method call should keep on running in different thread, how can we achieve this?
void ExecuteAfterTimeInterval()
{
//some code
}
public static void main(string[] args)
{
//call the below method after every 12 hours
ExecuteAfterTimeInterval();
// run the below code in separate thread
// some code here
//some code here
//some code here
}
Give this a try. Look for //SET BREAK POINT HERE and run.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace MyConsole
{
class Program
{
static void Main(string[] args)
{
Program console = new Program();
console.MyMethodAsync();
}
void ExecuteAfterTimeInterval()
{
//some code
}
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// run the below code in separate thread
//some code here
//some code here
for (int i = 0; i < 10000000000; i++)
{
Console.WriteLine(i); //SET BREAK POINT HERE
}
//some code here
//and now we call await on the task
int result = await longRunningTask;
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
bool retry = true;
using (AutoResetEvent wait = new AutoResetEvent(false))
{
while (retry)
{
//Do Work here
//await Task.Delay(43200000); //12 hour delay
await Task.Delay(3000); //SET BREAK POINT HERE
}
}
return 1;
}
}
}
I was experimenting with the new C# await feature. I made a custom awaiter implementation as follows:
using System;
using System.Runtime.CompilerServices;
using System.Threading;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
T1();
Console.WriteLine("After t1");
}
private static async void T1()
{
CustomAwaitable a = new Sleeper().Sleep();
object r = await a;
Console.WriteLine("sleeper awakes " + r);
}
}
internal class CustomAwaitable
{
private readonly Sleeper m_sleeper;
public CustomAwaitable(Sleeper s)
{
m_sleeper = s;
}
public MyAwaiter GetAwaiter()
{
return new MyAwaiter(m_sleeper);
}
}
internal class Sleeper
{
public ManualResetEvent Handle = new ManualResetEvent(false);
public bool Awake { get; set; }
public int Result
{
get { return Environment.TickCount; }
}
public CustomAwaitable Sleep()
{
new Thread(() =>
{
Thread.Sleep(5000);
Awake = true;
Handle.Set();
}).Start();
Console.WriteLine("begin sleeping " + Result);
return new CustomAwaitable(this);
}
}
internal class MyAwaiter : INotifyCompletion
{
private readonly Sleeper m_sleeper;
public MyAwaiter(Sleeper sleeper)
{
m_sleeper = sleeper;
}
public bool IsCompleted
{
get { return m_sleeper.Awake; }
}
public void OnCompleted(Action continuation)
{
// This works!!
//new Thread(() =>
//{
// m_sleeper.Handle.WaitOne();
// continuation();
//}).Start();
// This doesn't work!!
Action k = () =>
{
m_sleeper.Handle.WaitOne();
continuation();
};
k.BeginInvoke(null, null);
}
public object GetResult()
{
return m_sleeper.Result;
}
}
}
The problem is that, in the OnCompleted method, when I schedule the continuation code execution using BeginInvoke, the GetResult method is never called. But when I create a thread manually to do the same thing, everything works as expected. I know that BeginInvoke uses the thread pool internally, which should work the same way as the thread approach (I know that there is a thread count limit with thread pool, but it is negligible in this case as I am not running anything else).
What are your ideas? Thanks!
I have a console application that essentially looks like this
class Program
{
static void Main(string[] args)
{
DoStuffService svc = new DoStuffService();
svc.Start();
}
}
class DoStuffService
{
public void Start()
{
Task.Factory.StartNew(() => { LongRunningOperation() });
}
private void LongRunningOperation()
{
// stuff
}
}
What's the best way these days to ensure my console application doesn't exit before LongRunningOperation() is complete, and also allows me a way to be notified in the console application (for logging purposes for instance) that LongRunningOperation() is complete.
call Wait() on the task. For example:
class Program
{
static void Main(string[] args)
{
DoStuffService svc = new DoStuffService();
svc.Start();
// stuff...
svc.DelayTilDone();
}
}
public class DoStuffService
{
Task _t;
public void Start()
{
_t = Task.Factory.StartNew(() => { LongRunningOperation(); });
}
public void DelayTilDone()
{
if (_t==null) return;
_t.Wait();
}
private void LongRunningOperation()
{
System.Threading.Thread.Sleep(6000);
System.Console.WriteLine("LRO done");
}
}
In addition to Cheeso's answer, you'll want to handle Console.CancelKeyPress so that you can display a busy message and set e.Cancel = True.
There's nothing you can do to prevent them from killing the process, but you can at least handle Ctrl+C and Ctrl+Break.
There is a similar thread C# multi-threaded console application - Console quits before threads complete
You can simply return a started task and Wait() or ContinueWith() on it:
using System.Diagnostics;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
DoStuffService svc = new DoStuffService();
svc.Start().Wait();//bool res = svc.Start()
Trace.WriteLine("333333333333333");
}
}
public class DoStuffService
{
public Task Start()
{
return Task.Factory.StartNew
(() =>
{
Trace.WriteLine("111111111");
LongRunningOperation(); ;
});
}
private void LongRunningOperation()
{
System.Threading.Thread.Sleep(3000);
Trace.WriteLine("2222222222");
}
}
A task will block the parent thread until completion, if to access its Result property, so:
using System.Diagnostics;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
DoStuffService svc = new DoStuffService();
svc.Start();//bool res = svc.Start()
Trace.WriteLine("333333333333333");
}
}
public class DoStuffService
{
public Task<bool> MyTask;
public bool Start()
{
MyTask = Task.Factory.StartNew<bool>
(() =>
{
Trace.WriteLine("111111111");
return LongRunningOperation();;
});
return MyTask.Result;
}
private bool LongRunningOperation()
{
System.Threading.Thread.Sleep(3000);
Trace.WriteLine("2222222222");
return true;
}
}