繁体   English   中英

在 C# 程序中异步运行 C++ 代码

[英]Running C++ code asynchronously in a C# program

我在 C++ 中编写了一些后端代码,并在 C# 中为其编写了前端。 我想要它做的是在后台运行后端代码,这样我就可以做其他事情,比如更新进度条,但是当我点击“开始”按钮时,程序会挂起,直到它完成运行后端代码。

C# 代码:

    [DllImport("backend.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int executeBackend();

    private async void startButton_Click(object sender, EventArgs e)
    {
        startButton.Enabled = false;
        await StartProgram();
    }

    private async Task StartProgram()
    {
        int status = 0;
        status = executeBackend(); //This is causing the UI to deadlock
        startButton.Enabled = true;
    }

后端.dll C++ 代码:

extern "C" {
    __declspec(dllexport) int executeBackend()
    {
        int statusCode = 0;
        //Do stuff in the background
        return statusCode;
    }
}

如果我注释掉运行 executeBackend 的调用并将其替换为await Task.Delay(5000); ,用户界面不会死锁。 我将如何解决这个问题?

您可以将对executeBackend的调用包装在Task中以防止 UI 锁定。

var status = await Task.Run(() => executeBacked());

我还认为您对async关键字的实际作用感到困惑。 我认为阅读异步编程在 dotnet 中的工作原理可能是明智的。

您需要重新考虑您的 C++ 代码如何处理异步性。

您应该能够通过 C++ 端一个回调 function,以便您可以移交整个操作并返回一个Task

像这样的东西(注意StartProgram function 正在使用TaskCompletionSource并且标记为async 。)

[DllImport("backend.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void executeBackend(BackendCallback func);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void BackendCallback(int result);

private Task<int> StartProgram()
{
    var tcs = new TaskCompletionSource<int>();
    BackendCallback callback = result =>
    {
        tcs.SetResult(result);
        GC.KeepAlive(callback);  // prevent GC from disposing unmanaged callback
    };
    executeBackend(callback);
    return tcs.Task;
}

我对 C++ 不够熟悉,无法向您展示那一面。

但本质上,您需要能够获取void (*) (int) function 指针类型的参数,将操作移交给另一个线程,然后在完成时使用 ZC1C425264E68385D1ABZ5074 指针回调 C# 端。

暂无
暂无

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

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