Dispatcher中Invoke与BeginInvoke
[同步]Invoke
Application.Current.Dispatcher.Invoke(AutoIncreaseNumber);
[异步]BeginInvoke
Application.Current.Dispatcher.BeginInvoke((Action)AutoIncreaseNumber);
两者都会阻塞UI线程
基于WPF4.5.1示例
Invoke 按钮对应的是InvokeCommand
BeginInvoke按钮对应的是BeginInvokeCommand
可以发现,在执行按钮的命令时,UI线程是会阻塞,计时器并不会走动
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds();
timer.Tick += timer_Tick;
timer.Start();
} void timer_Tick(object sender, EventArgs e)
{
Now = DateTime.Now;
} private DateTime now = DateTime.Now; public DateTime Now
{
get { return now; }
set
{
now = value;
RaisePropertyChanged("Now");
}
} private int number;
/// <summary>
/// 数值用于显示
/// </summary>
public int Number
{
get { return number; }
set
{
number = value;
RaisePropertyChanged("Number");
}
} private bool isIncrease;
/// <summary>
/// 是否可以自增长
/// </summary>
public bool IsIncrease
{
get { return isIncrease; }
set
{
isIncrease = value;
RaisePropertyChanged("IsIncrease");
}
} /// <summary>
/// 自动增长
/// </summary>
private void AutoIncreaseNumber()
{
IsIncrease = !isIncrease;
while (IsIncrease && Number < )
{
Number++;
}
} #region RelayCommands
/// <summary>
/// Invoke命令
/// </summary>
public RelayCommand InvokeCommand
{
get
{
return new RelayCommand(() =>
{
Application.Current.Dispatcher.Invoke(AutoIncreaseNumber);
});
}
}
/// <summary>
/// BeginInvoke命令
/// </summary>
public RelayCommand BeginInvokeCommand
{
get
{
return new RelayCommand(() =>
{
//这里直接使用匿名方法会报错
//'Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type'
//使用强制转换的方式
Application.Current.Dispatcher.BeginInvoke((Action)AutoIncreaseNumber);
});
}
}
/// <summary>
/// 清理数字命令
/// </summary>
public RelayCommand ClearCommand
{
get
{
return new RelayCommand(() =>
{
Number = ;
IsIncrease = false;
});
}
}
#endregion
}
注:其中阻塞UI线程的原因是把Number的递增放到了Dispather中去执行,如果想要不阻塞,那么需要有一个新的DispatcherTimer的对象去执行这个递增的逻辑,那么就不会阻塞UI线程了。
所以说这里所说的异步并不是相对于UI线程的异步,那么究竟是什么?
Invoke 是同步操作;因此,直到回调返回之后才会将控制权返回给调用对象。
BeginInvoke 是异步操作;因此,调用之后控制权会立即返回给调用对象。
--- msdn
做一个测试
/// <summary>
/// DiffInInvokeAndBeginInvoke.xaml 的交互逻辑
/// </summary>
public partial class DiffInInvokeAndBeginInvoke : Window
{
public DiffInInvokeAndBeginInvoke()
{
InitializeComponent();
this.ltb.ItemsSource = _infos;
this.Loaded += DiffInInvokeAndBeginInvoke_Loaded;
} private ObservableCollection<string> _infos = new ObservableCollection<string>(); private void DiffInInvokeAndBeginInvoke_Loaded(object sender, RoutedEventArgs e)
{
ExcuteMethod();
ExcuteMethod_2();
ExcuteMethod_3();
} private void ExcuteMethod()
{
Dispatcher.Invoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.SystemIdle, "1-1: SystemIdle Invoke");
Dispatcher.Invoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Send, "1-2: Send Invoke ");
Dispatcher.BeginInvoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Normal, "1-3: Normal BeginInvoke");
Dispatcher.BeginInvoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Send, "1-4: Send BeginInvoke");
DispatcherOperation dop = Dispatcher.BeginInvoke(new Action<string>(PrintInformation), "1-5: Defaut BeginInvoke");
} private void ExcuteMethod_2()
{ Dispatcher.BeginInvoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Normal, "2-1: Normal BeginInvoke");
Dispatcher.Invoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Send, "2-2: Send Invoke ");
Dispatcher.BeginInvoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Send, "2-3: Send BeginInvoke");
} private void ExcuteMethod_3()
{
Dispatcher.Invoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Send, "3-1: Send Invoke ");
Dispatcher.BeginInvoke(new Action<string>(PrintInformation), System.Windows.Threading.DispatcherPriority.Send, "2-2: Send BeginInvoke");
} private void PrintInformation(string info)
{
_infos.Add(info);
}
}
结果如下:
从结果及MSDN对于Invoke及BeginInvoke的解释,很容易就理解了。
Invoke一定要执行完了才会执行下去,而BeginInvoke是没有等待执行完就接着往下走了,然后会根据线程的调用优先级开始执行。
Dispatcher中Invoke与BeginInvoke的更多相关文章
- .Net基础——程序集与CIL HttpClient封装方法 .Net Core 编码规范 C#中invoke和beginInvoke的使用 WebServeice 动态代理类
.Net基础——程序集与CIL 1. 程序集和CIL: 程序集是由.NET语言的编译器接受源代码文件产生的输出文件,通常分为 exe和dll两类,其中exe包含Main入口方法可以双击执行,dll ...
- C#中Invoke 和 BeginInvoke 的区别
Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托. Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句 ...
- C#中Invoke和BeginInvoke的区别
1.Invoke() 调用时,Invoke会阻止当前主线程的运行,等到 Invoke() 方法返回才继续执行后面的代码,表现出“同步”的概念. 2.BeginInvoke() 调用时,当前线程会启用线 ...
- WPF Invoke和BeginInvoke
在WPF中Invoke和BeginInvoke和Winform中的是差不多的,只是一个用Control的一个用Dispatcher的. 而Invoke和BeginInvoke的区别嘛 就是一个是同步的 ...
- [转载]Winform中Control的Invoke与BeginInvoke方法
转自http://www.cppblog.com/baby-fly/archive/2010/04/01/111245.html 一.为什么 Control类提供了 Invoke和 BeginInvo ...
- C#中的Invoke和BeginInvoke
一.Control#Invoke() 和Control#BeginInvoke() 在非UI线程中调用MessageBox.Show()结果是非模态对话框: 在UI线程中调用MessageBox.Sh ...
- 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)
[分析]浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang) 今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间 ...
- C#中Control的Invoke和BeginInvoke是相对于支线线程
近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下. Control的Invoke和BeginInvoke 是相对于支线线程(因为一般在支线线程中调用, ...
- C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和Begin ...
随机推荐
- 第三百三十三天 how can I 坚持
为什么感觉那么累呢,老想睡觉. 晚上勇江请吃饭,其实内心是拒绝的,好伐,老想回家尽快睡觉. 今天说是要搞oauth认证的东西,看的一头雾水. 想的太简单了.其实也不难.apache的东西,都封装好的. ...
- Spark的发展历程
·2009年:Spark诞生于AMPLab.·2010年:开源.·2013年6月:Apache孵化器项目.·2014年2月:Apache顶级项目.·2014年2月:大数据公司Cloudera宣称加大S ...
- 【转】Java transient关键字
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看到某个成员变量的同一 ...
- SQL SERVER安装提示“安装了 Microsoft Visual Studio 2008 的早期版本
工作共遇到的问题记录: 安装Sql Server 2008 R2时提示错误:“此计算机上安装了 Microsoft Visual Studio 2008 的早期版本.请在安装 SQL Server 2 ...
- AutoCAD.NET二次开发错误集锦
1.CAD崩溃,错误“unhandled access violation reading”=“未将对象引用设置到对象的实例”. 2. 建模操作错误:指向给定边的指针为空. 建模操作错误:访问冲突. ...
- 利用UIImagePickerController或者利用UIKit的 UIGraphicsBeginImageContext保存图片
转载自:http://my.oschina.net/hmj/blog/99970 应用中有时我们会有保存图片的需求,如利用UIImagePickerController用IOS设备内置的相机拍照 ...
- sql数据库delete删除后怎么恢复,这是网上找的答案。。希望大神验证指教一下
使用Log Explorer查看和恢复数据 Log Explorer 4.1.可用于SQL Server2005的日志查看工具 下载地址: http://download.csdn.net/sourc ...
- Cocos2d-x 关于在iOS平台真机测试的一些注意
下面简单记录一下在最近cocos2d-x项目在iOS平台真机测试和模拟器测试中遇到的一些要注意的地方(使用ipod): 1.图片大小 游戏中基本上都是会用到图片,那么在使用图片的时候要特别注意图片的s ...
- 函数WideCharToMultiByte() 详解
函数原型: int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPWSTR lpWideCharStr, int cchWideChar, ...
- CMSIS Example - Signal and Yield
/*---------------------------------------------------------------------------- * RL-ARM - RTX *----- ...