Async&Await IL Code - c#

If i implement a default async/await method like:
class Program
{
static void Main(string[] args)
{
new Program().TestMethod();
}
private async void TestMethod()
{
await Task.Delay(10);
}
}
The generated IL-Code and the async state machine contains a field "this" with a reference to the instance which invoked the method. If the code is adjusted to a static one, there is of course no "this" value.
Not to do this via reflection, more from perspective of the CLR or the debugger.
Does anyone know how i can determine within the "static TestMethod" from which method i was called - on the IL level!
class Program
{
static void Main(string[] args)
{
TestMethod();
}
private static async void TestMethod()
{
await Task.Delay(10);
}
}

how i can determine within the "static TestMethod" from which method i was called
You can use CallerMemberName attribute
static void Main(string[] args)
{
new Program().TestMethod();
Console.ReadLine();
}
private async void TestMethod([CallerMemberName]string caller = "")
{
Console.WriteLine(caller);
}
PS: You can also use CallerFilePath or CallerLineNumber

using System;
using System.Diagnostics;
namespace Cli
{
class Program
{
static void Main(string[] args)
{
new Program().TestMethod();
}
private void TestMethod()
{
var sf = new StackFrame(1); //get caller stackframe
var mi = sf.GetMethod(); //get method info of caller
Console.WriteLine("{0}::{1}", mi.DeclaringType, mi.Name);
// Cli.Program::Main
}
}
}

Related

Can I have two entry points in C#

Would it be possible to use two entry points in C# instead of just having the one. For example when I have this:
using System;
namespace learning
{
class cool
{
static void Main(string[] args)
{
}
}
}
Would it be possible to have another entry point such as secondary that the program executes once the main entry point has finished.
You may want to do something like this:
class Program {
public static void EntryPoint1(string[] args) {
// Code
}
public static void EntryPoint2(string[] args) {
// Code
}
public static void Main(string[] args) {
EntryPoint1(args);
EntryPoint2(args);
}
}
Just make sure to not modify args during EnteryPoint1 or if you want to, clone them like this:
class Program {
public static void EntryPoint1(string[] args) {
// Code
}
public static void EntryPoint2(string[] args) {
// Code
}
public static void Main(string[] args) {
EntryPoint1(args.Clone());
EntryPoint2(args.Clone());
}
}
In C#, you specify the entry point using the /main: compiler option.
Imagine that the code containing containing two main() methods as follow :
namespace Application {
class ClassA {
static void main () {
// Code here
}
}
class ClassB {
static void main () {
// Code here
}
}
To use ClassA.main() as your entry point, you would specify the following when compiling:
csc /main:Application.ClassA hello.cs
You can only have a single entry point, but you can write two separate methods, call the first one, and then the second one. You will achieve what you're describing.
using System;
namespace learning
{
class cool
{
static void Main(string[] args)
{
PartOne();
PartTwo();
}
void PartOne() {
// Something happens here
}
void PartTwo() {
// Something else happens here
}
}
}
Additionally (depending on how the program starts up) you can send in arguments to specify which method you want to execute (if you don't need both of them to execute). Then you can just do an "if/else" statement that will decide which method to run depending on the arguments passed into Main

Execute code from string in net core runtime?

For example we have such a class:
namespace ConsoleApp1
{
public class Program
{
public int x = 0;
public int y = 1;
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Program program = new Program();
program.RunScript(Console.ReadLine());
}
public void RunScript(string script)
{
//....
}
public void CallMethod1()
{
}
public void CallMethod2()
{
}
}
}
And in the console I want to enter an expression for execution, in the language C#:
"if(x > y){CallMethod1();}else{CallMethod2();}"
how can this expression be executed? I've seen examples with Roslyn https://learn.microsoft.com/en-us/archive/msdn-magazine/2017/may/net-core-cross-platform-code-generation-with-roslyn-and-net-core
but they call static functions or functions from the new namespace, but I need to call a function that is already in the current namespace

Call Methode in process from c#-project

I want to call a public Methode(Send) in a process from my c# project!
This is the process with the Methode that i want to call :
namespace Test123
{
class Program
{
static void Main(string[] args)
{
while(true)
{
}
}
public void Send()
{
Console.WriteLine("Test");
}
}
}
I know how to get the process but not how to invoke the methode!
I already searched on other websites and i dinĀ“t found anything that helps me.
Create a instance of the program in the static and call the method.
class Program
{
static void Main(string[] args)
{
var p = new Program();
while(true)
{
p.Send();
}
}
public void Send()
{
Console.WriteLine("Test");
}
}
If your in the same Program class, you can just call the method. The other approach listed where you declare a new Program, would be needed if you were in a different class.
static void Main(string[] args)
{
while(true)
{
Send();
}
}

Call function from Main()

I am new to C# and I'm having a little problem with calling a function from the Main() method.
class Program
{
static void Main(string[] args)
{
test();
}
public void test()
{
MethodInfo mi = this.GetType().GetMethod("test2");
mi.Invoke(this, null);
}
public void test2()
{
Console.WriteLine("Test2");
}
}
I get a compiler error in test();:
An object reference is required for the non-static field.
I don't quite understand these modifiers yet so what am I doing wrong?
What I really want to do is have the test() code inside Main() but it gives me an error when I do that.
If you still want to have test() as an instance method:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.test();
}
void Test()
{
// I'm NOT static
// I belong to an instance of the 'Program' class
// You must have an instance to call me
}
}
or rather make it static:
class Program
{
static void Main(string[] args)
{
Test();
}
static void Test()
{
// I'm static
// You can call me from another static method
}
}
To get the info of a static method:
typeof(Program).GetMethod("Test", BindingFlags.Static);
Just put all logic to another class
class Class1
{
public void test()
{
MethodInfo mi = this.GetType().GetMethod("test2");
mi.Invoke(this, null);
}
public void test2()
{
Console.Out.WriteLine("Test2");
}
}
and
static void Main(string[] args)
{
var class1 = new Class1();
class1.test();
}
The method must be static in order to call it.

Aluminum Lua - register function

How do you register Lua method info (of static public void) to a context in AluminiumLua?
You can achieve this by providing a delegate matching your method's signature.
using System;
using AluminumLua;
public delegate void HelloDelegate();
class Program
{
public static void Hello()
{
Console.Write("Hello world!");
}
static void Main()
{
var context = new LuaContext();
var obj = LuaObject.FromDelegate(new HelloDelegate(Hello));
context.SetGlobal("hello", obj);
context.Get("hello").AsFunction().Invoke(new LuaObject[] { });
}
}

Categories

Resources