首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >阻塞UI线程的方法

阻塞UI线程的方法
EN

Stack Overflow用户
提问于 2018-06-09 03:02:05
回答 2查看 511关注 0票数 1

我最近创建了一个辅助方法来限制属性更改事件的速度,以便在给定延迟的情况下将数据保存到我的本地数据库。我遇到的唯一问题是该方法显然没有异步运行,并且阻塞了我的UI线程。

为了测试它,我将SettingsViewModel中的事件附加到PercentageSliderViewModel

代码语言:javascript
复制
public class SettingsViewModel : BaseVM
{
    public PercentageSliderViewModel Activity { get; set; }

    [...]

    public SettingsViewModel() {
        Activity.PropertyChanged += CreateThrottledCallback(Save, 1000);
    }

    [...]

    public async Task Save()
    {
        // Save data
    }
}

这是我的辅助方法:

代码语言:javascript
复制
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方法,这样它就不会阻塞我的主线程?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-11 22:47:52

还不清楚您的Save方法到底做了什么,也不清楚它是否是真正的异步方法。您可以尝试在CreateThrottledCallback方法中的后台线程中执行它:

代码语言:javascript
复制
if (callback != null)
    await Task.Run(() => callback.Invoke());
票数 1
EN

Stack Overflow用户

发布于 2018-06-09 03:20:16

因为它与UI无关,所以您可以使用ConfigureAwait(false)。这将避免捕获当前同步上下文,并且任务将在TaskScheduler.Default线程池上下文中运行。

代码语言:javascript
复制
await callback().ConfigureAwait(false);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50766942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档