[同步]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的更多相关文章

  1. .Net基础——程序集与CIL HttpClient封装方法 .Net Core 编码规范 C#中invoke和beginInvoke的使用 WebServeice 动态代理类

    .Net基础——程序集与CIL   1. 程序集和CIL: 程序集是由.NET语言的编译器接受源代码文件产生的输出文件,通常分为 exe和dll两类,其中exe包含Main入口方法可以双击执行,dll ...

  2. C#中Invoke 和 BeginInvoke 的区别

    Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托. Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句 ...

  3. C#中Invoke和BeginInvoke的区别

    1.Invoke() 调用时,Invoke会阻止当前主线程的运行,等到 Invoke() 方法返回才继续执行后面的代码,表现出“同步”的概念. 2.BeginInvoke() 调用时,当前线程会启用线 ...

  4. WPF Invoke和BeginInvoke

    在WPF中Invoke和BeginInvoke和Winform中的是差不多的,只是一个用Control的一个用Dispatcher的. 而Invoke和BeginInvoke的区别嘛 就是一个是同步的 ...

  5. [转载]Winform中Control的Invoke与BeginInvoke方法

    转自http://www.cppblog.com/baby-fly/archive/2010/04/01/111245.html 一.为什么 Control类提供了 Invoke和 BeginInvo ...

  6. C#中的Invoke和BeginInvoke

    一.Control#Invoke() 和Control#BeginInvoke() 在非UI线程中调用MessageBox.Show()结果是非模态对话框: 在UI线程中调用MessageBox.Sh ...

  7. 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)

    [分析]浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang) 今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间 ...

  8. C#中Control的Invoke和BeginInvoke是相对于支线线程

    近日,被Control的Invoke和BeginInvoke搞的头大,就查了些相关的资料,整理如下. Control的Invoke和BeginInvoke 是相对于支线线程(因为一般在支线线程中调用, ...

  9. C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别

    在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和Begin ...

随机推荐

  1. 转】用Maven构建Hadoop项目

    原博文出自于: http://blog.fens.me/hadoop-maven-eclipse/ 感谢!   用Maven构建Hadoop项目 Hadoop家族系列文章,主要介绍Hadoop家族产品 ...

  2. JVM系列四:生产环境参数实例及分析【生产环境实例增加中】

    java application项目(非web项目) 改进前: -Xms128m-Xmx128m-XX:NewSize=64m-XX:PermSize=64m-XX:+UseConcMarkSweep ...

  3. Bash's ArithmeticExpression

    [Bash's ArithmeticExpression] let command: let a=17+23 echo "a = $a" # Prints a = 40 let a ...

  4. 了解 JavaScript 中的内置对象

    所有编程语言都具有内部(或内置的)对象来创建 语言的基本功能.内部对象是 您编写自定义代码所用语言的基础, 该代码基于您的想象实现自定义功能.JavaScript 有许多 将其定义为语言的内部对象.本 ...

  5. UVa 11536 Smallest Sub-Array (水题, 滑动窗口)

    题意:给定 n 个由0~m-1的整数组成的序列,输入 k ,问你找出连续的最短序列,使得这个序列含有1-k的所有整数. 析:这个题,很简单么,只要从头开始扫一遍就OK,时间复杂度为O(n). 代码如下 ...

  6. Weka EM 协方差

    Weka EM covariance description 1: Dear All, I am trying to find out what is the real meaning of the ...

  7. 用DependanceProperty做Dynamic换Icon

    1:做Icon用Canvas还是DrawingBrush? Canvas的例子:

  8. 32.怎样在Swift中实现TabBar和导航视图结合的项目?

    导航栏和TabBar结合的项目,在我们平常开发中会经常看到,下面我们通过自定义的TabBar来实现一个导航和TabBar结合的Demo. 1.自定义TabBar import UIKit class ...

  9. 【转】android出现注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 注: 某些输入文件使用了未经检查或不安全的操作。 注

    使用Android studio打包应用程序出现如下错误: 注: 某些输入文件使用或覆盖了已过时的 API. 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译. 注: 某些 ...

  10. 查看系统和PowerShell版本

    查询PowerShell当前版本$psversiontable.BuildVersion.Major 查询Windows当前版本:[System.Environment]::OSVersion.Ver ...