您的位置:首页 > 产品设计 > UI/UE

非阻塞式UI思路

2015-12-17 14:44 176 查看
想做到非阻塞式UI是一个比较复杂的过程:

1.首先需要弄清楚在用户等待的这段时间,UI的其它部分是否还能继续接受用户的输入?如果可以,那需要找到一种UI设计模式,例如使用状态栏来反映当前操作的状态。如果不用,那一个带有进度条的模态对话框应该就足够了。

2程序完成计算或者是拿到了数据后,需要给用户一个反馈。鉴于你使用的是C#,那大部分时候这个反馈是体现在UI上的。这里C#的WinForm或者WPF程序需要注意的是,UI操作必须得从UI线程(一般就是主线程)上执行。如果程序是在非UI线程上完成了计算或者拿到了数据,它不能直接操作UI的(否则会引发异常)。正确的做法是从非UI线程上向UI线程上发送一个消息;UI线程接收到这个消息后执行相应的操作。

3.最高效的异步操作是利用某种消息-通知机制来实现Idle Wait,而你在贴出来的代码里做的事情叫Busy Wait。

具体到代码上,大概是这样一个流程:

1.用户点击了UI,想要触发一个操作。此时UI的event handler代码不可以直接执行那个耗时的操作。它要么开启一个新线程,在新线程上执行那个操作;要么如果有相应的异步API的话,调用相应的异步API就可以达到一样的效果。

2.如果要开启一个新线程,新线程的入口函数在执行了耗时的操作之后,需要向UI线程发送一个消息。如果是WinForm程序,可以是Form.Invoke(或者任何控件上的".Invoke")。这个函数会在内部判断当前线程是否是UI线程:如果是UI线程,它就直接执行UI操作;如果不是UI线程,就往UI线程上发送个消息,然后UI线程会把这个函数重新执行一遍,就回到了前一种情况,把实际的UI操作完成了。

3/如果是相应的异步API,还要看异步API是哪种:

1.如果是返回Task或Task<T>的,还是要回到#2(新建一个线程,在新线程上做async/await)。

2.如果是Begin/End风格的,在传进去的callback函数里做“向UI线程发送一个消息”这件事情。

很久没有做C#的UI编程了,以上是凭着大概记忆来的。如果你可以把情况讲得更具体一点,我可以更针对性的提出建议。

如果你想从高层了解应该怎样做,大概需要以下几个方面的知识:异步编程;OS级别的event API(可选,有助于了解.NET这种高层框架的异步编程是怎么从OS底层包装上来的);UI应用程序的线程分配;WinForm/WPF的UI操
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c# 思想