如何处理从 .Net 外部调用的库中的 async/await 用法?
How to handle async/await usage in a library called from outside .Net?
我是 C# 这个领域的新手,坦率地说,我正在努力理解范例。看来我不是一个人(, http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html)
在我的例子中,我在 C# 库中编写一个小型 TCP 服务器,本质上,TCP 服务器应该 运行 在它自己的线程中,并且 post 数据通过提供的回调返回到应用程序.所以我们可能有一个进入库的入口点:
class MyServer
{
void StartServerRunningAsync(Callback callback)
{
this.callback = callback; //calls back into unmanaged via 'magic' COM interop each time a TCP client posts interesting data
StartRunningThread(); //this creates a thread to run the server and returns
}
void StartRunningThread()
{
new Thread(new ThreadStart(Run)).Start();
}
void Run()
{
//do standard TCP async stuff treating `Run` like a local `Main`
}
}
该库将在非托管 C++ 应用程序(在本例中特别是通过 COM)中使用,该应用程序 运行 是后台服务器。所以我不认为 StartServerRunning
can/should 是 async
但这意味着我 stuck/confused 如何使用 async
/await
所有这些都是因为它会根据上面的链接在您的整个堆栈中传播。
这真的是个问题还是我误解了一些基本的东西? TPL怎么可以这样封装?
实际上,使用 async/await 让事情变得更容易。
class MyServer
{
// notice async void here instead of async Task
async void StartServerRunning(Callback callback)
{
await StartRunningThreadAsync(); // start server asynchronously
callback();
}
}
从外部观察者的角度来看,StartServerRunning
在遇到第一个等待时立即退出。但是在后台,方法还是"running"。一旦 StartRunningThreadAsync
完成,就会调用 callback
。当在 C# 代码中使用时,这不是一个好的做法,但当涉及 C 互操作时,我不认为这是一件坏事。
我还建议实现异常处理,这样任何异常都不会超出此方法。喜欢:
class MyServer
{
async void StartServerRunning(Callback callback)
{
bool wasError = false;
try{
await StartRunningThreadAsync(); // start server asynchronously
}catch(Exception ex)
{
// log exception
wasError = true;
}
callback(wasError);
}
}
我是 C# 这个领域的新手,坦率地说,我正在努力理解范例。看来我不是一个人(
在我的例子中,我在 C# 库中编写一个小型 TCP 服务器,本质上,TCP 服务器应该 运行 在它自己的线程中,并且 post 数据通过提供的回调返回到应用程序.所以我们可能有一个进入库的入口点:
class MyServer
{
void StartServerRunningAsync(Callback callback)
{
this.callback = callback; //calls back into unmanaged via 'magic' COM interop each time a TCP client posts interesting data
StartRunningThread(); //this creates a thread to run the server and returns
}
void StartRunningThread()
{
new Thread(new ThreadStart(Run)).Start();
}
void Run()
{
//do standard TCP async stuff treating `Run` like a local `Main`
}
}
该库将在非托管 C++ 应用程序(在本例中特别是通过 COM)中使用,该应用程序 运行 是后台服务器。所以我不认为 StartServerRunning
can/should 是 async
但这意味着我 stuck/confused 如何使用 async
/await
所有这些都是因为它会根据上面的链接在您的整个堆栈中传播。
这真的是个问题还是我误解了一些基本的东西? TPL怎么可以这样封装?
实际上,使用 async/await 让事情变得更容易。
class MyServer
{
// notice async void here instead of async Task
async void StartServerRunning(Callback callback)
{
await StartRunningThreadAsync(); // start server asynchronously
callback();
}
}
从外部观察者的角度来看,StartServerRunning
在遇到第一个等待时立即退出。但是在后台,方法还是"running"。一旦 StartRunningThreadAsync
完成,就会调用 callback
。当在 C# 代码中使用时,这不是一个好的做法,但当涉及 C 互操作时,我不认为这是一件坏事。
我还建议实现异常处理,这样任何异常都不会超出此方法。喜欢:
class MyServer
{
async void StartServerRunning(Callback callback)
{
bool wasError = false;
try{
await StartRunningThreadAsync(); // start server asynchronously
}catch(Exception ex)
{
// log exception
wasError = true;
}
callback(wasError);
}
}