当触发这个事件进入后. 为了不让逻辑处理的时间耽搁后续事件的触发传递. 我做了如下两个方案. 我想知道这两个方案有什么利弊
注意:假设 触发Receive 那边确实会等待这个函数,我处理完成后,才会二次触发本函数
一直无法深层次理解这个问题,困擾我很久. 我在线程内部. 经常二次嵌套以下两种用法. begininvoke 和 Task.Factory.StartNew .请指点一二
网上很多贴子看过了. 还是无法深层次理解.
方案一
private static void Receive(string msg)
{
new Action(delegate () {
//记录 msg 日志,并做逻辑处理
}).BeginInvoke(null,null);
}
方案二
private static void Receive(string msg)
{
Task.Factory.StartNew(delegate () {
//记录 msg 日志,并做逻辑处理
});
}
Task.Factory.StartNew安排委托(delegate)以在线程池线程。当前线程继续运行,而无需等待此任务的结果(异步)。通常,您会生成一个运行时间更长的后台任务,以使UI不会被阻塞太长时间(而不是“卡住”)。
Dispatcher.BeginInvoke安排委托(delegate)以在调度程序(UI)线程。通常,这样做是为了更新某些用户界面,控制具有在某个对象上执行的某些操作的结果后台线程。
单纯从效率的角度上来讲,建议使用Task来进行操作。
这两个方案区别的本质是在 action 与 task的区别
我的最终目的就是为了. 不卡触发事件的线程. 如果有更好的方案. 也希望大家指导下
new Action(delegate () {}).BeginInvoke(null,null);是在触发时事件的线程上异步执行,本例中本质上还是没有换线程(当然也可以换线程,根据应用场景需要),Task.Factory.StartNew(delegate () {});是启动新的线程上执行。我觉得从你的目的和执行效率上来讲,不影响当前线程,不卡触发事件的线程,Task都更加符合一些。有帮助请采纳谢谢!
插个眼
看了前面的答案觉得有点异议,这里要区分Action.BeginInvoke和Dispatcher.BeginInvoke,这是两个东西。
Action.BeginInvoke也是实现异步的一种方式,这种情况下其实是通过调用线程池的线程来执行代码,不会和调用者属于同一线程,因为当前的调用者线程不会是空闲线程,看测试代码:
这种调用方式在本质上其实和使用Task没有区别,因为最终执行代码还是线程,但是从效率上来看,确实是Task性能高,所以在实现异步的时候推荐Task。
而Dispatcher.BeginInvoke其实和你这个问题没有太大的关系,这是另一种用法, Dispatcher是消息泵,利用线程上下文向UI线程发送消息来调度UI线程,一般用于在子线程中更新UI元素。