SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文。 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为。此模型还简化了托管应用程序为在不同的同步环境下正常工作而必须遵循的一些要求。同步模型的提供程序可以扩展此类并为这些方法提供自己的实现。(来自MSDN)
简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色。另外这里有个地方需要清楚的,不是每个线程都附加SynchronizationContext这个对象,只有UI线程是一直拥有的。

Console, WinForm和WPF中的SynchronizationContext

Console程序中没有SynchronizationContext的概念。这也很好理解。因为Console没有UI控件,所以也不需要SynchronizationContext来进行同步。SynchronizationContext.Currnet总是为null。
在WinForm中,如果我们只创建了一个Window,SynchronizationContext.Currnet为一个类型为System.Windows.Forms.WindowsFormsSynchronizationContext的

System.Windows.Forms.WindowsFormsSynchronizationContext。但是如果你接下来用Application.Run()来显示这个窗口,SynchronizationContext.Currnet又变成了System.Threading.SynchronizationContext类型。不过有一点可以保证,在WinForm程序中SynchronizationContext.Currnet一定不为空。

在WPF中,不管你怎么创建Window,也不管你怎么用Applicaitono.Run()函数来启动Window,SynchronizationContext.Currnet总是为空。我们必须显示初始化:SynchronizationContext.SetSynchronizationContext(new System.Windows.Threading.DispatcherSynchronizationContext());

winform通过上下文更新控件内容

        SynchronizationContext sc = SynchronizationContext.Current;       

        #region SynchronizationContext
//https://www.bbsmax.com/A/ZOJPX24eJv/ 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件
/// <summary>
/// This method is executed on the main UI thread.
/// </summary>
private void UpdateUI(object state)
{
string msg = state as string;
SendLogMessage(msg);
return;
Invoke(new MethodInvoker(delegate ()
{
if (RtbMsg != null)
{
RtbMsg.AppendText(msg + "\r\n");
RtbMsg.ScrollToCaret();
}
}));
}
/// <summary>
/// 交给UI线程去排队显示消息
/// </summary>
/// <param name="message"></param>
private void SendLogMessage(string message)
{
sc.Post(LogMessageBack, message);
}
/// <summary>
/// UI线程回调方法,访问控件刷新显示
/// </summary>
/// <param name="message">消息内容</param>
private void LogMessageBack(object message)
{
RtbMsg.AppendText(message.ToString() + Environment.NewLine);
RtbMsg.ScrollToCaret();
}
#endregion SynchronizationContext

  

        protected internal static System.AsyncCallback SyncCallback(System.AsyncCallback callback)
{
System.Threading.SynchronizationContext sc = System.Threading.SynchronizationContext.Current;
if (sc == null)
{
return callback;
}
return delegate(System.IAsyncResult asyncResult)
{
sc.Post(delegate(object result)
{
callback((System.IAsyncResult)result);
}, asyncResult);
};
}
protected void DataAction(Action action)
{
try
{
action();
}
catch (System.Exception ex)
{
OperateLog.OpExcpLog(string.Format("[{0}][{1}]功能操作执行异常,异常原因:{2}", action.Method.GetType().FullName, action.Method.Name, ex.Message));
System.Windows.Forms.MessageBox.Show(EESException.getException(ex).Message, "异常警告", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Hand);
}
}
protected void BeginAction(MethodDelegate action, object obj, params object[] args)
{
EForm.AsyncRequest asyncRequest = new EForm.AsyncRequest(action, obj, args, System.Threading.SynchronizationContext.Current);
this.inAsyncAction = null;
this.OnBeginAction(asyncRequest);
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.OnWaitCallback), asyncRequest);
}
protected void BeginAction(object proxy, string command, params object[] args)
{
MethodDelegate action = FastInvoke.CreateMethodDelegate(proxy.GetType().GetMethod(command));
this.BeginAction(action, proxy, args);
}
protected void BeginActionWithToolTip(MethodDelegate action, object obj, string toolTip, params object[] args)
{
EForm.AsyncRequest asyncRequest = new EForm.AsyncRequest(action, obj, args, System.Threading.SynchronizationContext.Current, toolTip);
this.inAsyncAction = null;
this.OnBeginAction(asyncRequest);
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.OnWaitCallback), asyncRequest);
}
protected void BeginActionWithToolTip(object proxy, string command, string toolTip, params object[] args)
{
MethodDelegate action = FastInvoke.CreateMethodDelegate(proxy.GetType().GetMethod(command));
this.BeginAction(action, proxy, new object[]
{
toolTip,
args
});
}
protected virtual void OnBeginAction(EForm.AsyncRequest context)
{
if (this.waitingForm.Visible)
{
throw new EESException("后台正在执行,请稍候……");
}
this.waitingForm.Message = context.ToolTip;
this.waitingForm.Show();
}
protected virtual void OnEndAction(EForm.AsyncResponse context)
{
this.waitingForm.Visible = false;
}
private void OnWaitCallback(object state)
{
EForm.AsyncRequest asyncRequest = (EForm.AsyncRequest)state;
object result = null;
System.Exception exception = null;
try
{
result = asyncRequest.Method(asyncRequest.Obj, asyncRequest.Args);
}
catch (System.Exception ex)
{
exception = ex;
}
EForm.AsyncResponse state2 = new EForm.AsyncResponse(asyncRequest.Method, result, asyncRequest.Args, exception);
System.Threading.SynchronizationContext context = asyncRequest.Context;
if (context != null)
{
context.Post(new System.Threading.SendOrPostCallback(this.OnSendOrPostCallback), state2);
}
}
private void OnSendOrPostCallback(object state)
{
EForm.AsyncResponse asyncResponse = (EForm.AsyncResponse)state;
this.OnEndAction(asyncResponse);
if (asyncResponse.Exception != null)
{
System.Windows.Forms.MessageBox.Show(EESException.getException(asyncResponse.Exception).Message);
return;
}
this.OnActionComplete(asyncResponse);
}
protected virtual void OnActionComplete(EForm.AsyncResponse context)
{
}

  这是摘录的项目里面基类窗体关于SynchronizationContext的封装,子类只要使用各种BeginAction就行了,然后在OnActionComplete里面处理访问UI控件的操作.

通过同步上下文方式更新winform中的控件信息的更多相关文章

  1. Winform中checklistbox控件的常用方法

    Winform中checklistbox控件的常用方法最近用到checklistbox控件,在使用其过程中,收集了其相关的代码段1.添加项checkedListBox1.Items.Add(" ...

  2. [C#]WinForm 中 comboBox控件之数据绑定

    [C#]WinForm 中 comboBox控件之数据绑定 一.IList 现在我们直接创建一个List集合,然后绑定 IList<string> list = new List<s ...

  3. Winform中Treeview控件失去焦点,将选择的节点设置为高亮显示 (2012-07-16 13:47:07)转载▼

    Winform中Treeview控件失去焦点,将选择的节点设置为高亮显示 (2012-07-16 13:47:07)转载▼标签: winform treeview drawnode Treeview控 ...

  4. C# WinForm中 让控件全屏显示的实现代码

    夏荣全 ( lyout(at)163.com )原文 C#中让控件全屏显示的实现代码(WinForm) 有时候需要让窗口中某一块的内容全屏显示,比如视频播放.地图等等.经过摸索,暂时发现两种可行方法, ...

  5. Winform中TextBox控件开启自动提示补全功能

    问题:Winform开发中,有一个TextBox控件用以输入姓名,现希望在输入名字时能够自动提示所有可能的名字. 解答:winform中的TextBox控件含有如下三个属性:   ① AutoComp ...

  6. Winform 中DataGridView控件添加行标题

    有很多种方法. 1.可以在DataGridView控件中的RowStateChanged事件改变行标题单元格的值(Row.HeaderCell.Value) /// <summary> / ...

  7. Winform中Picture控件图片的拖拽显示

    注解:最近做了一个小工具,在Winform中对Picture控件有一个需求,可以通过鼠标从外部拖拽图片到控件的上,释放鼠标,显示图片! 首先你需要对你的整个Fom窗口的AllowDrop设置Ture ...

  8. C# WinForm中NotifyICon控件的用法

    参考:http://blog.csdn.net/paullink520/article/details/14170021 http://www.cnblogs.com/webman/archive/2 ...

  9. winform中comboBox控件加默认选项的问题

    winform程序设计中,label,TextBox,ComboBox等几个控件几乎是用得最多的,在设计中经常会遇到一些小问题,如:comboBox控件绑定了数据源之后,如何设置默认值? combob ...

随机推荐

  1. __main__ 变量

    1. 摘要 通俗的理解__name__ == '__main__':假如你叫小明.py,在朋友眼中,你是小明(__name__ == '小明'):在你自己眼中,你是你自己(__name__ == '_ ...

  2. 错误代码errno值的含义

    错误代码errno值的含义 查看错误代码errno是调试程序的一个重要方法.当C api函数发生异常时,一般会将errno变量(需include errno.h)赋一个整数值,不同的值表示不同的含义, ...

  3. SpringBootMVC02——SpringDataJpa与ThymeLeaf

    大纲 - SpringDataJpa进阶使用- SpringDataJpa自定义查询- 整合Servlet.Filter.Listener- 文件上传- Thymeleaf常用标签 1.整合Servl ...

  4. Spring Framework Part1

    初识Spring 1.Spring是一个支持IOC(Inversion of Control),DI(Dependency Injection),AOP(Aspect Oriented Program ...

  5. ThinkPHP中的SQL结果分析

    ThinkPHP中的SQL结果分析 在进行结果判断时需要注意. 一.查询SQL: 可能出现的情况:1.查询成功,返回正常数据.2.查询成功,但是没有数据,返回NULL.3.查询错误,写错关键字.结果: ...

  6. Ubuntu 16.04 orb-slam2配置

    说明:Ubuntu 16.04以及必要的基础软件安装完成之后进行: 1.OpenNI2安装(可选) 安装依赖项: sudo apt--dev freeglut3-dev doxygen graphvi ...

  7. Windows navcat 连接虚拟机mysql

    linux下mysql的安装与使用 https://www.cnblogs.com/shenjianping/p/10984540.html linux安装mysql教程 https://www.cn ...

  8. css不常见属性之pointer-events

    MDN 上介绍为 CSS 属性指定在什么情况下 (如果有) 某个特定的图形元素可以成为鼠标事件的 target.pointer-events 属性值有: /* Keyword values */ po ...

  9. 创建一个jFinal项目

    最近在做微信开发,于是用到了jfinal. 做一下解释: JFinal 是基于 Java 语言的极速 WEB + ORM 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩 ...

  10. ESP8266--WIFI热点扫描

    现在,通常,为了让手机连上一个WiFi热点,基本上都是打开手机设置里面的WiFi设置功能,然后会看到里面有个WiFi热点列表,然后选择你要的连接上. 基本上你只要打开手机连接WiFi功能,都会发现附近 ...