[同步]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. 著名加密库收集 Encrypt

    CryptoAPI 微软的CryptoAPI crypt32.lib,advapi32.lib,cryptui.lib #include <wincrypt.h>#include < ...

  2. delphi 集合

    DELPHI没有JAVA的丰富的集合(SET MAP LIST),只有Tlist,可包装各种类型

  3. Deep Learning 学习笔记——第9章

    总览: 本章所讲的知识点包括>>>> 1.描述卷积操作 2.解释使用卷积的原因 3.描述pooling操作 4.卷积在实践应用中的变化形式 5.卷积如何适应输入数据 6.CNN ...

  4. 如何在Html的CSS中去除<li>标签前面小黑点,和ul、LI部分属性方法

    div是很多人做网站都会用到的,但在显示效果时前面总是会有一个小黑点,这个效果很多人不想要,但又不知到如何去除,然而我们可以用以下方法来清除. 1.在CSS中写入代码.找到相关性的CSS,在..li和 ...

  5. javascript 汉字生成拼音

    在网上下载的一个汉字生成拼音的js,很有用,大家一起分享! var PinYin = {"a":"/u554a/u963f/u9515","ai&qu ...

  6. uva10327 - Flip Sort

    Flip Sort Sorting in computer science is an important part. Almost every problem can be solved effec ...

  7. linux下mysql开启慢查询

    mysql中最影响速度的就是那些查询很慢的语句.这些慢的语句,可能是写的不够合理或者是大数据下多表的联合查询等等.所以我们要找出这些语句,分析原因,加以优化. 1.方法1:用命令开启慢查询 1).查看 ...

  8. ssh-keygen 无密码登陆需要注意一个问题

    从今天开始记录一下工程上的小知识. ssh-keygen -t rsa cat id_rsa.pub >> authorized_keys后,切记,将authrorized_keys文件的 ...

  9. SQL with(unlock)与with(readpast) (转)

    所有Select加 With (NoLock)解决阻塞死锁,在查询语句中使用 NOLOCK 和 READPAST 处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAS ...

  10. jquery 新建的元素事件绑定问题

    js的事件监听跟css不一样,css只要设定好了样式,不论是原来就有的还是新添加的,都有一样的表现.而事件监听不是,你必须给每一个元素单独绑定事件. 常见的例子是处理表格的时候.每行行末有个删除按钮, ...