我在MSDN中采用了以下示例,用于在WinRT应用程序的列表视图中逐步加载缩略图:
https://code.msdn.microsoft.com/windowsapps/Data-Binding-7b1d67b5
我想删除下面的“await Task.Delay(10)”行。 当我这样做时,我得到一个警告,该方法缺少await运算符。
protected async override Task<IList<object>> LoadMoreItemsOverrideAsync(System.Threading.CancellationToken c, uint count)
{
uint toGenerate = System.Math.Min(count, _maxCount - _count);
// Wait for work
await Task.Delay(10);
// This code simply generates
var values = from j in Enumerable.Range((int)_count, (int)toGenerate)
select (object)_generator(j);
_count += toGenerate;
return values.ToArray();
}
我尝试重写该方法并将整个方法包装在一个任务中,如下所示:
protected async override Task<IList<object>> LoadMoreItemsOverrideAsync(System.Threading.CancellationToken c, uint count)
{
return await Task.Run(() => {
uint toGenerate = System.Math.Min(count, _maxCount - _count);
// This code simply generates
var values = from j in Enumerable.Range((int)_count, (int)toGenerate)
select (object)_generator(j);
_count += toGenerate;
return values.ToList<object>();
});
}
但是,我正在获得线程异常:
异常:应用程序调用了为不同线程编组的接口。 (来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))
好像我需要在UI线程上运行它?但我无法访问Dispatcher。
寻找一些建议
答案 0 :(得分:0)
我认为你在寻找错误的地方。当然,我在黑暗中采取了一些刺激,但由于其余部分在您的_generator(int)
方法中看起来无害,因此很可能需要在UI线程上运行。 (也许它不是UI线程本身,但是某些东西需要在与其他东西相同的线程上运行。既然你提到缩略图,最可能的原因是你创建了一个GDI + Graphics对象一个线程,并试图在另一个线程中操纵它。)
我的建议是仔细检查你的_generator(int)
方法并制作一个async
版本,以确保代码在正确的线程上运行。这样就可以保持封装,并且LoadMoreItemsOverrideAsync
回调不需要了解_generator
的内部工作原理。
作为旁注,添加10毫秒的延迟几乎肯定不正确的操作,除非您正在积极尝试避免某些竞争条件。 (评论中“等待工作”是什么意思?如果你确实在等待工作,你不应该等待另一项任务完成,而不是任意10ms吗?)
您最有可能发出的警告是试图告诉您,“您已使用async
关键字标记此方法,但没有任何关于它的信息是异步的。您是否在某个地方忘记了await
?”
如果作为最后的手段,你别无选择,只能同步运行代码,就这样做。在那里发表评论,并通过禁用该方法的特定警告来确认情况。