In case a method takes too long it would make sense to terminate it after a timeout.
Is it possible to implement Method like BreakMyMethod_afterTimeout?
public static void MyMethod()
{
//some code
}
public static async void BreakMyMethod_afterTimeout(int timeoutInSec)
{
//break MyMethod after timeout
}
public static void main()
{
BreakMyMethod_afterTimeout(60); //Is this possible to relize?
MyMethod();
//the program continues here after 60 seconds at the latest
}
Related
currently I'm using a timer to poll every x seconds. I've seen that I could also use asyncronous tasks to execute a function after x seconds.
So I've created an example for reproduction. This is how I would use a polling timer
class UseTimer
{
public UseTimer()
{
Console.WriteLine("Foo");
Timer myTimer = new Timer(2000);
myTimer.Elapsed += (object sender, ElapsedEventArgs e) =>
{
Console.WriteLine("Bar");
myTimer.Enabled = false;
};
myTimer.Enabled = true;
Console.ReadLine();
}
}
The code first logs Foo, then waits 2 seconds for the first timer tick and then logs Bar. I tried to reproduce it by using async/await
class UseAsync
{
public UseAsync()
{
Console.WriteLine("Foo");
Do().Wait();
Console.ReadLine();
}
private async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}
The behaviour seems to be the same when I test it with this code
class Program
{
static void Main(string[] args)
{
// UseAsync a = new UseAsync();
UseTimer t = new UseTimer();
}
}
I would like to know if I could or even should switch to async because it's easier to maintain and takes out complexity but remains the same way under the hood.
"Every x seconds" is different from "after x seconds".
If you need to run something (repeatedly) every x seconds, use a Timer.
If you need to run something (only once) after x seconds, use Task.Delay.
As noted in the comments, Task.Delay uses a System.Threading.Timer anyway, it's just easier to use for a single wait, and keeps your code clean.
Also, it's not wise to use asynchronous methods in a class constructor. Class constructors cannot be async, and thus you end up blocking the thread (as you did when using Wait()), or "fire and forget". If you need to do anything asynchronous while creating a new object, you can use a "factory method": a static method that creates the object for you. Then you make the constructor private to force everyone to use the factory method:
class UseAsync
{
private UseAsync() {}
public static async Task<UseAsync> CreateUseAsync()
{
var myC = new UseAsync();
await myC.Do();
return myC;
}
private async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}
Then you can create an instance like this:
var a = await UseAsync.CreateUseAsync();
I've done this when I need to retrieve data from somewhere before an object is actually useful.
The console.readline should be outside useAsync method, if not the task Do will not be executed
class Program
{
static void Main(string[] args)
{
UseAsync.UseAsyn();
Console.ReadLine();
}
}
static class UseAsync
{
public static async Task UseAsyn()
{
Console.WriteLine("Foo");
await Do();
}
private static async Task Do()
{
await Task.Delay(2000);
Console.WriteLine("Bar");
}
}
I have an application where I would like to execute certain orders on a certain thread when that thread is idling. So I created a manager to handle this for me, launched of a form.show and created a thread manager:
public class ThreadManager
{
static List<ThreadAble> orders = new List<ThreadAble>();
public static bool running = false;
public static void execute(ThreadAble action)
{
orders.Add(action);
}
public static void RegisterAPIThreadAndHold()
{
running = true;
Application.Idle += Application_Idle;
}
private static void Application_Idle(object sender, EventArgs e)
{
if (orders.Count != 0)
{
ThreadAble f = orders.First();
orders.Remove(f);
f.execute();
}
}
}
public interface ThreadAble {
void execute();
}
public static class formstuff{
private static void ShowDialogThreaded(){
form.Show(owner);
ThreadManager.RegisterAPIThreadAndHold();
}
}
}
I then try to use this using it by:
public class TestRegister : ThreadAble
{
public void execute()
{
throw new NotImplementedException();
}
}
ThreadManager.execute(new TestRegister());
Now this should throw an exception, however it doesn't. I have also tried with more complicated behaviour and breakpoints but this code seems to never get executed. Am I misunderstanding how the Application_Idle works? Is there another way to make it so that this thread starts executing my code (has to be this thread) when it's done with handling the GUI code and not doing anything else (it might be required to do other things a well).
I already veritfied that RegisterAPIThreadAndHold() is executed.
To demonstrate asynchronous flow of C# I have written a simple program
( To show its difference from Python, as Python is synchronous because of GIL).
Why is execution of func2() waiting for func1() to finish?
void main()
{
Console.WriteLine("main");
func1();
func2();
}
public void func1()
{
Console.WriteLine("func1");
double i = 0;
while(true)
{
i += 1;
if (i > 100000000)
{
break;
}
}
func(3);
func(4);
}
public void func2()
{
Console.WriteLine("func2");
func(5);
func(6);
}
public void func(int number)
{
Console.WriteLine(number);
}
In func1(), I am running a loop to make program wait so that main() keep going and call func2() before func(3) and func(4). But every time, it runs in a synchronous fashion and print output in this order :
main
func1
3
4
func2
5
6
i.e. func2() is always called after func4() which I didn't expect in asynchronous flow.
Why is execution of func2() waiting for func1() to finish?
Thanks
C# does not make your program synchronous. All programs are synchronous (exception of multi-core). Even the OS runs synchronously and only gives the illusion of parallel processing by giving various programs time slices of execution. If you want your program to run parallel you have to explicitly tell it so. C#/.NET have many mechanisms to do this but it is not fair to say a language is asynchronous. Multi-thread code can be written in C to run on windows but if you are working on an embedded system that doesn't support parallel processing you cant.
If you want func2 not to wait for func1 to finish, you need to tell it so:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("main");
doWork();
}
public async static void doWork()
{
Task<int> longTask = func1(); //Start func1
func2(); //Call func2 while we wait
int output = await longTask; //Wait for func2 to be finished
}
public async static Task<int> func1()
{
Console.WriteLine("func1");
await Task.Delay(10000); //delay, could make func(3) and func(4) run in the meantime if we wanted....
func(3);
func(4);
return 0;
}
public static void func2()
{
Console.WriteLine("func2");
func(5);
func(6);
}
public static void func(int number)
{
Console.WriteLine(number);
}
}
Outputs:
main
func1
func2
5
6
3
4
This happens because every time a method is invoked, in C#, the information passed to the parameter is stored in a stack (call stack). This stack is implemented as first in last out.
So in your example when the func1 is invoked it goes to stack, the main method will stop and wait for the func1 to leave the stack.
https://en.wikipedia.org/wiki/Call_stack
There is no way to do what you want without asynchronous flow and I suspect it is the same for python, too.
However you can easily change your code to execute it asynchronous.
public static void Main()
{
Console.WriteLine("main");
var t = func1();
func2();
t.Wait();
}
public static Task func1()
{
Console.WriteLine("func1");
return Task.Factory.StartNew(() => {
double i = 0;
while(true)
{
i += 1;
if (i > 100000000)
{
break;
}
}
func(3);
func(4);
});
}
public static void func2()
{
Console.WriteLine("func2");
func(5);
func(6);
}
public static void func(int number)
{
Console.WriteLine(number);
}
I want to call Method2 and then Method1. I know there are multiple ways of doing this like Method1(Method2());
But I just tried the below code.
In the below scenario Method2 is not getting called. So I'm just curious to know where this scenario is useful, why C# has provided this mechanism.
public delegate void Action();
public static void Method1(Action action)
{
}
static void Main()
{
Method1(Method2);
return;
}
public static void Method2()
{
}
You should invoke action within Method1:
...
public static void Method1(Action action)
{
// do not forget to validate input for public methods
if (null == action)
throw new ArgumentNullException("action");
action(); // you should invoke action
}
I have one class with these three methods. This class is used by many threads.
I would like the Method1 to wait, if Method2 and/or Method3 are running in any threads.
Any suggestions?
public class Class1
{
public static void Method1()
{
Object lockThis = new Object();
lock (lockThis)
{
//Body function
}
}
public static void Method2()
{
//Body function
}
public static void Method3()
{
//Body function
}
}
If I understood correctly, you need something like this:
static object lockMethod2 = new object();
static object lockMethod3 = new object();
public static void Method1()
{
lock (lockMethod2)
lock (lockMethod3)
{
//Body function
}
}
public static void Method2()
{
lock (lockMethod2)
{
//Body function
}
}
public static void Method3()
{
lock (lockMethod3)
{
//Body function
}
}
This allows method3 to execute if method2 is running and vice versa, while method1 must wait for both. Of course, method2 and 3 will not run while 1 is running.
The current implementation of your lock is completely useless, because every thread will lock on a different object.
Locking is usually done with a readonly field that is initialized only once.
Like this, you can easily lock multiple methods:
public class Class1
{
private static readonly object _syncRoot = new object();
public static void Method1()
{
lock (_syncRoot)
{
//Body function
}
}
public static void Method2()
{
lock (_syncRoot)
{
//Body function
}
}
public static void Method3()
{
lock (_syncRoot)
{
//Body function
}
}
}
I would suggest a ReaderWriterLockSlim (http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx)
Similar to read operations, Method 2 and Method3 may occur in parallel, while Method1 (like a write operation) would need to wait for those to finish.
It's not the regular read/write concurrency situation, but the logic is similar.
public class Class1
{
private ReaderWriterLockSlim methodLock = new ReaderWriterLockSlim();
public static void Method1()
{
methodLock.EnterWriteLock();
try
{
//Body function
}
finally
{
methodLock.ExitWriteLock();
}
}
public static void Method2()
{
methodLock.EnterReadLock();
try
{
//Body function
}
finally
{
methodLock.ExitReadLock();
}
}
public static void Method3()
{
methodLock.EnterReadLock();
try
{
//Body function
}
finally
{
methodLock.ExitReadLock();
}
}
}
If you are multi-threading then the lock has to be accessible to all threads. Therefore, in this case, your locks needs to be static for the static methods to see it.
Your current setup will make a new lock object for each thread. Therefore, providing now synchronization.