我最近创建了一个辅助方法来限制属性更改事件的速度,以便在给定延迟的情况下将数据保存到我的本地数据库。我遇到的唯一问题是该方法显然没有异步运行,并且阻塞了我的UI线程。
为了测试它,我将SettingsViewModel
中的事件附加到PercentageSliderViewModel
public class SettingsViewModel : BaseVM
{
public PercentageSliderViewModel Activity { get; set; }
[...]
public SettingsViewModel() {
Activity.PropertyChanged += CreateThrottledCallback(Save, 1000);
}
[...]
public async Task Save()
{
// Save data
}
}
这是我的辅助方法:
public PropertyChangedEventHandler CreateThrottledCallback(
Func<Task> callback, int throttle = 1000)
{
bool throttling = false;
bool callFinal = false;
return async(s, e) =>
{
if (throttling)
{
callFinal = true;
return;
}
throttling = true;
await callback?.Invoke();
await Task.Delay(throttle).ContinueWith(_ => throttling = false);
if (callFinal)
{
await callback?.Invoke().ContinueWith(_ => callFinal = false);
}
};
}
尽管节流工作正常,但当我从左向右移动滑块时,回调发生时,它会在一小段时间内“冻结”。
调试显示它正在UI线程上运行。
如何异步运行CreateThrottledCallback
方法,这样它就不会阻塞我的主线程?
发布于 2018-06-11 22:47:52
还不清楚您的Save
方法到底做了什么,也不清楚它是否是真正的异步方法。您可以尝试在CreateThrottledCallback
方法中的后台线程中执行它:
if (callback != null)
await Task.Run(() => callback.Invoke());
发布于 2018-06-09 03:20:16
因为它与UI无关,所以您可以使用ConfigureAwait(false)
。这将避免捕获当前同步上下文,并且任务将在TaskScheduler.Default
线程池上下文中运行。
await callback().ConfigureAwait(false);
https://stackoverflow.com/questions/50766942
复制相似问题