我正在寻找一种在后台执行任务的简单方法,然后在完成时更新某些内容(在主线程上).它处于低级“模型”类中,因此我无法调用InvokeOnMainThread,因为我没有NSObject.我有这个方法:
public void GetItemsAsync(Action<Item[]> handleResult) { Item[] items=null; Task task=Task.Factory.StartNew(() => { items=this.CreateItems(); // May take a second or two }); task.ContinueWith(delegate { handleResult(items); },TaskScheduler.FromCurrentSynchronizationContext()); }
这似乎工作正常,但是
1)这是最好的(最简单的)方式吗?
2)我担心局部变量:
Item{} items=null
谢谢.
解决方法
我认为你的方法略有违反
Single Responsibility Principle,因为它做得太多了.
首先,我建议更改CreateItems以返回Task而不是将其包装在GetItemsAsync中:
public Task<Item[]> CreateItems(CancellationToken token) { return Task.Factory.StartNew(() => // obtaining the data... {}); }
CancellationToken是可选的,但如果您能够取消这个长时间运行的操作,它可以帮助您.
使用此方法,您可以完全删除GetItemsAsync,因为客户端处理结果非常简单,而无需传递此委托:
// Somewhere in the client of your class var task = yourClass.CreateItems(token); task.ContinueWith(t => // Code of the delegate that prevIoUsly // passed to GetItemsAsync method {},TaskScheduler.FromCurrentSynchronizationContext());
使用这种方法,您将获得更清晰的代码,只有一个责任. Task类本身是将异步操作表示为first class object的完美工具.使用提议的技术,您可以轻松地模拟当前实现,并使用虚假行为进行单元测试,而无需更改客户端代码.