一种WPF在后台线程更新UI界面的简便方法 - Fixing - 博客园

WPF框架规定只有UI线程(主线程)可以更新界面,所有其他后台线程无法直接更新界面。幸好,WPF提供的SynchronizationContext类以及C#的Lambda表达式提供了一种方便的解决方法。以下是代码:

public static SynchronizationContext s_SC = Synchronization.Current; //主窗口类的静态成员

在App类中:

static volatile int s_nMainThreadID = Thread.CurrentThread.ManagedThreadId; //这个变量保存主线程ID(UI线程),为下面的属性服务,注意volatile修饰符,如果不用的话,在Release版本的程序可能会出错。

//这个属性表示当前执行线程是否在主线程中运行

public static bool IsRunInMainThread { get { return Thread.CurrentThread.ManagedThreadId == s_nMainThreadID;}}

//这个函数用于设置UI界面上的某个元素

public void SetText(string strText)

{

  if (!App.IsRunInMainThread)

  {

    s_SC.Post(oo => { SetText(strText); }, null); //可以使用Post也可以使用Send

    return;

  }

  textBlock1.Text = strText;

}

//这个函数用于从UI界面的元素获取内容

public string GetText()

{

  if (!App.IsRunInMainThread)

  {

    string str = null;

    s_SC.Send(oo => { str = GetText(); }, null);   //必须要使用Send

    return str;

  }

  return textBlock1.Text;

}

说明:虽然在主线程,也可以使用SynchronizationContext来更新界面,但那样做会导致性能大幅下降。例如以下两句语句的性能差距大约是15倍(假设都在主线程调用):

textBlock1.Text = "Hello";               //执行100万次用时1秒

s_SC.Send(oo => { textBlock1.Text = "Hello"; }, null);   //执行100万次用时15秒

所以,每次执行界面更新函数时,判断是否在主线程执行是必要的。


原网址: 访问
创建于: 2024-06-19 19:03:39
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论