[英]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.