Using C# async method on c++
Asked Answered
L

0

7

I made a class library (.net framework) project in C# and I want to use that DLL on my C++ client project.

I've checked on MSDN and online for instructions on how to I made it. So I could see C# code's result on my c++ project. except on C# async method.

A runtime error has occurred there.

This is parts of my C# dll code.

namespace NethereumDLLTest
{
    [Guid("1C3D53B3-54C5-452B-9505-3F58ABEB35BA")]
    public interface INethereumDLL
    {
        void Run();
    }

    [Guid("C22875F1-B74D-4C99-B446-ED705CE86D3B")]
    public class Class1 : INethereumDLL
    {

        //there are some methods here.

        public void Run()
        {
            Console.WriteLine("NethereumDLLTEST");

            RunGeth();

            Task task = new Task(ActionMethod);
            task.Start();
            Console.WriteLine("Main Logic");

            GetAccountBalance().Wait();
            Console.ReadLine();
        }

        static async Task GetAccountBalance()
        {
            for (int i = 10; i > 0; i--)
            {
                Thread.Sleep(1000);
            }
            var web3 = new Web3("http://localhost:8545");
            var balance = await  web3.Eth.GetBalance.SendRequestAsync("0xb3a11b62596b8b6313dddc30e9b11607c8f9fb38");

            Console.WriteLine($"Balance in Wei: {balance.Value}");
            var etherAmount = Web3.Convert.FromWei(balance.Value);
            Console.WriteLine($"Balance in Ether: {etherAmount}");
        }
    }
}

and here are cpp client's codes.

#import "C:\Users\june\source\repos\NethereumDLLTest\NethereumDLLTest\bin\Debug\NethereumDLLTest.tlb" 

using namespace std;
using namespace NethereumDLLTest;

int main()
{

    CoInitialize(NULL);

    {
        INethereumDLLPtr ptr(__uuidof(Class1));
        ptr->Run();
    }
    CoUninitialize();

}

I could find all log message above "GetAccountBalance" function, but it looks like it hasn't been executed after that.

Can't use C# async functions in c++? or Did I something wrong?

runtime error capture image

Lumpy answered 30/10, 2018 at 5:55 Comment(8)
I see you're using COM. COM does not work well with C#'s async paradigm. You need to modify your C++ code to keep the main thread alive so that your program will still be running when the continuation runs.Hermit
You are calling the C# function from C++. Can you make the complete C# chain Async, currently public void Run(), calling the ` GetAccountBalance()` is not async, this might be causing a hang as GetAccountBalance().Wait() is blocking the calling threadImmesh
I believe your code works OK. You can make sure that by putting a getChar() just after ptr->Run();. Like @Hermit mentioned async await is .net implementation detail so it may not have 1 to 1 mapping on c++ side. You should also notice that since async is implementatio ndetail you can not define async on interfaces either :)Paschasia
Moreover, unless you have a very very very compelling reason you should never ever use new Task()Paschasia
Oh very thank you guys. yes I used COM. @MrinalKamboj, you mean make sure that run method is async right? I'll do that.Lumpy
There's arguably nothing wrong with a COM client using a c# COM server that is using async just so long as you essentially wait for the task to finish before you return from .NET side. Though explicitly waiting for an async task to finish (like you are doing anyway) kind of defeats the purpose of async/awaitModish
I wanna communicate with ethereum blockchain geth client. ethereum supports module for .net framework named 'Nethereum'. but we have developed in c++, so I should find the way how to use Nethereum on c++ codes. As you guys can see like "web3.Eth.GetBalance.SendRequestAsync", Nethereum offer async methods and I just have to use on c++.Lumpy
COM has no concept of asynchronous calls. The only thing you can do is mark is as thread safe (UI thread only) or notModish

© 2022 - 2024 — McMap. All rights reserved.