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