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