我正在为机器人控制器创建一个包装库,它主要依赖于P/Invoke调用.
但是,机器人的许多功能(例如归位或移动)需要很长时间,并且在运行时执行线程锁定.
所以我想知道如何以异步方式包装功能,因此调用不会阻止我的UI线程.到目前为止我的想法是使用任务,但我不确定这是正确的方法.
public TaskHomeAsync(Axis axis, CancellationToken token) { return Task.Factory.StartNew(() => Home(axis), token); }
目前关于.NET中Async模型的大多数MSDN文章主要是在已经具有异步功能的库(例如File.BeginRead等)上进行转发.但我似乎无法找到有关如何实际编写异步功能的更多信息.
你有没有试过异步代表?我相信没有什么比它简单了.
如果您的线程阻塞方法是void Home(Axis)
您首先定义委托类型,即.delegate void HomeDelegate(Axis ax)
,然后使用BeginInvoke
HomeDelegate的新实例的方法指向Home方法的地址.
[DllImport[...]] //PInvoke void Home(Axis x); delegate void HomeDelegate(Axis x); void main() { HomeDelegate d = new HomeDelegate(Home); IAsyncResult ia = d.BeginInvoke(axis, null, null); [...] d.EndInvoke(ia); }
请记住,在某处使用EndInvoke(阻塞线程,直到方法最终结束,可能与IAsyncResult.Completed属性的轮询一起)对于检查您的异步任务是否真的已经完成非常有用.您可能不希望机器人打开它的手臂并留下玻璃杯,直到玻璃杯在桌子上方,你知道;-)
经过一番讨论,我觉得这样的事情将成为黄金的中间道路.
public void HomeAsync(Axis axis, Actioncallback) { Task.Factory .StartNew(() => Home(axis)) .ContinueWith(task => callback(task.Result)); }
我认为这是两全其美的.