[英]Asynchronous API for Streaming Data from a Hardware Device
我正在用C#编写一个库,但我需要使它异步。 通常,您公开一组DLL函数,它们接受输入参数,并在完成时返回一个值。 但是我怎样才能创建一个库函数(可以从C ++ / Delphi / Etc中调用),它在开始输入的同时已经开始流回输出?
我现在看到的唯一解决方案是使用套接字/管道/等进行通信,而不是DLL调用。
有人有一个例子如何使用普通的DLL调用吗?
一个简单的异步库调用(位于System.dll
)的一个好模型是WebClient.DownloadStringAsync 。 此方法异步从Uri
下载,并在完成时引发DownloadStringCompleted事件。
您的库同样可以提供FooAsync
方法,该方法不会阻止当前线程,但只要有些数据进入您的库就会引发FooDataReceived
事件,并在计算完成时FooCompleted
事件。
微软在这件事上有一篇很好的文章。 如果你只是在EndInvoke上移动它,它也应该适合你。 http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.71).aspx
由于您希望输入和输出都是异步的,因此您将需要一个工作线程:如果既不能阻止输入线程也不能阻止输出线程,那么两者都不会费心去做。
您已经考虑过通过管道进行通信,但为什么要使用管道而不是内部结构?
所以你在输入上有这个无锁队列,在输出上有另一个队列和一个工作线程
工作线程从inqueue获取输入,处理它,将其放入出队
如果输入队列变空,那么工作线程没有什么可以处理,所以他引发了“需要更多数据”事件,然后在输入队列上阻塞变为(部分)满
如果工作线程将某些内容放入输出队列,则会引发“有更多数据”事件,如果输出队列变为(完全)满,则会阻止输出空间变为可用
您的API是非阻塞的:发送输入和接收输出都没有阻塞
您的API是异步的:给出了通知(通过事件)
根据OP的评论,调用应用程序向DLL发送音频,DLL通过某些USB接口发送音频,DLL从麦克风接口捕获一些音频,需要在应用程序发送时将捕获的音频发送回应用程序音频到DLL等
基于此以及呼叫可以用不同语言编写的事实我看到了一些通信渠道的选项:
我喜欢以下方法,因为它使客户端非常简单。
// your library
class Foo {
public event EventHandler ComputeCompleted = (sender, e) => { };
public void Compute() {
// kick off work on a background thread
// possibly using the BackgroundWorker object
var bw = new BackgroundWorker();
bw.RunWorkerCompleted += RunWorkerCompleted;
bw.RunWorkerAsync();
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
ComputeCompleted(this, new object());
}
}
// calling code
Foo foo = new Foo();
foo.ComputeCompleted += Completed;
foo.Compute();
private void Completed(object Sender, EventArgs e) {
// process the result here
}
要点是您启动库中立即返回的方法,然后通过事件/委托通知调用者处理完成。 然后,您可以根据需要自由地将执行调用回UI线程。
显然,错误处理不包含在示例代码中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.