繁体   English   中英

如何创建异步功能?

[英]How can i create an async function?

我的C ++类中有几个成员函数,这些成员函数将它们打包为dll,并试图在C#应用程序中使用它们。
我试图通过使用线程简单地执行两个异步函数,然后分离它们来创建两个异步函数,以使它们直到结束都不会阻塞调用者线程。 在基于C ++的应用程序中,每当我使用线程以这种方式调用函数时,它们都起作用,但是当我尝试从c#调用我的异步函数之一时,我的应用程序崩溃或挂起!
这些是我所谓的异步函数!:

void xGramManipulator::CreateMonoGramAsync()
{
    thread t(&xGramManipulator::ReadMonoGram, this);
    t.detach();
}

void xGramManipulator::CreateBiGramAsync()
{
    thread t = thread(&xGramManipulator::ReadBiGram, this);
    t.detach();
}

这是驻留在dll中的c中的包装函数:

//header
CDLL_API void CreateMonoGramAsync(void);
//cpp
CDLL_API void CreateMonoGramAsync(void)
{
    xG.CreateMonoGramAsync();
}

这是调用该函数的c#应用程序:

 private void btnTest_Click(object sender, EventArgs e)
 {
     try
     {
        CreateBiGramAsync();
        CreateMonoGramAsync();
     }
     catch (Exception)
     {
     }

}

我应该怎么做才能在课堂上拥有真正的异步和非阻塞成员函数? 我在这里想念什么?

我的猜测是,在将这些导入到C#中时没有指定调用约定-默认情况下,C#将使用stdcall而C ++将导出为cdecl 您将必须:

[DllImport("CDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void CreateMonoGramAsync();

或者,您当然可以在用C ++声明方法时指定returntype __stdcall 我还假设您已经正确地声明了该函数(带有extern "C" __declspec(dllexport)等)

如果使用的是.NET 4.5,则可以使用Task类来实现异步方法调用。

考虑以下示例:

    static void Foo()
    {
        Thread.Sleep(2000);
        Console.WriteLine("Foo called asynchronously!");
    }

    static void Main(string[] args)
    {
        var bar = Task.Factory.StartNew(() => { Foo(); });

        Console.WriteLine("Called synchronously!");

        Console.ReadLine();
    }

每当执行此代码时,将启动对Foo()的异步调用,该调用将等待两秒钟,然后以Foo called asynchronously!写入Foo called asynchronously! 到控制台。 另一个Console.WriteLine调用是同步的,并且在异步调用启动后立即运行。

输出为:

Called synchronously!
Foo called asynchronously!

由于调用方的线程不受Foo()的调用的阻塞。

您可以对代码执行相同的操作,甚至可以删除方法中当前具有的线程以使其异步。 原因是,即使它们创建了自己的线程,.NET运行时仍将等待这些函数返回。 您最好这样打给他们:

Task.Factory.StartNew(CreateBiGramAsync());

这样,它们实际上可以从.NET本身被异步调用,并且它们不会阻塞调用者线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM