通过同步上下文方式更新winform中的控件信息
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中的控件信息的更多相关文章
- Winform中checklistbox控件的常用方法
Winform中checklistbox控件的常用方法最近用到checklistbox控件,在使用其过程中,收集了其相关的代码段1.添加项checkedListBox1.Items.Add(" ...
- [C#]WinForm 中 comboBox控件之数据绑定
[C#]WinForm 中 comboBox控件之数据绑定 一.IList 现在我们直接创建一个List集合,然后绑定 IList<string> list = new List<s ...
- Winform中Treeview控件失去焦点,将选择的节点设置为高亮显示 (2012-07-16 13:47:07)转载▼
Winform中Treeview控件失去焦点,将选择的节点设置为高亮显示 (2012-07-16 13:47:07)转载▼标签: winform treeview drawnode Treeview控 ...
- C# WinForm中 让控件全屏显示的实现代码
夏荣全 ( lyout(at)163.com )原文 C#中让控件全屏显示的实现代码(WinForm) 有时候需要让窗口中某一块的内容全屏显示,比如视频播放.地图等等.经过摸索,暂时发现两种可行方法, ...
- Winform中TextBox控件开启自动提示补全功能
问题:Winform开发中,有一个TextBox控件用以输入姓名,现希望在输入名字时能够自动提示所有可能的名字. 解答:winform中的TextBox控件含有如下三个属性: ① AutoComp ...
- Winform 中DataGridView控件添加行标题
有很多种方法. 1.可以在DataGridView控件中的RowStateChanged事件改变行标题单元格的值(Row.HeaderCell.Value) /// <summary> / ...
- Winform中Picture控件图片的拖拽显示
注解:最近做了一个小工具,在Winform中对Picture控件有一个需求,可以通过鼠标从外部拖拽图片到控件的上,释放鼠标,显示图片! 首先你需要对你的整个Fom窗口的AllowDrop设置Ture ...
- C# WinForm中NotifyICon控件的用法
参考:http://blog.csdn.net/paullink520/article/details/14170021 http://www.cnblogs.com/webman/archive/2 ...
- winform中comboBox控件加默认选项的问题
winform程序设计中,label,TextBox,ComboBox等几个控件几乎是用得最多的,在设计中经常会遇到一些小问题,如:comboBox控件绑定了数据源之后,如何设置默认值? combob ...
随机推荐
- SQL注入的一些技巧分享
先上一道简单的ctf注入题: 一道利用order by进行注入的ctf题 很不错的一道利用order by的注入题,之前不知道order by除了爆字段还有这种操作. 原题地址:http://chal ...
- springmvc中的全注解模式
1.贴在类上: @Controller表明其是一个控制器 2.贴在方法上: @requestMapping("/xxx"): 标明请求要访问的方法的资源路径,,需以/打头.其中省略 ...
- 【AST篇】教你如何编写 Eslint 插件
前言 虽然现在已经有很多实用的 ESLint 插件了,但随着项目不断迭代发展,你可能会遇到已有 ESLint 插件不能满足现在团队开发的情况.这时候,你需要自己来创建一个 ESLint 插件. 本文我 ...
- vue点击出现蒙版
需求: 1.点击一个事件时弹出一个蒙版: 2.蒙版上有取消,删除事件:(点击取消时候蒙版消失,点击删除时,删除蒙版并消失): 3.点击空白地方,蒙版也消失: <template> ...
- 多层 iframe 嵌套 js 方法调用
一下午一个这破问题,浪费了不少时间,怎么也实现不了我的上上级iframe 刷新.NND. 实现了,记录一下下吧: window.parent.parent.document.getElementByI ...
- 2019-11-29-dotnet-使用-System.CommandLine-写命令行程序
title author date CreateTime categories dotnet 使用 System.CommandLine 写命令行程序 lindexi 2019-11-29 08:33 ...
- mongoose 开源http库(2) --HTTP服务示例
要创建HTTP服务器,请按照以下格式: 通过调用mg_bind()或mg_bind_opt()创建侦听连接 调用mg_set_protocol_http_websocket()创建listening连 ...
- SpringBootMVC02——Spring Data JPA的使用&JSP的使用
Spring Data JPA的使用 实体层 package com.littlepage.domain; import javax.persistence.Entity; import javax. ...
- C语言实现栈代码
/* 栈的特性:先进后出. 栈在计算语言处理和将递归算法改为非递归算法等方面起着非常重要的作用. */ #define INITSIZE 100 //储存空间的初始分配量 typedef int El ...
- Java 缓存池(使用Map实现)
之前只是听说过缓存池,也没有具体的接触到,今天做项目忽然想到了用缓存池,就花了一上午的时间研究了下缓存池的原理,并实现了基本的缓存池功能. /** * 缓存池 * @author xiaoquan * ...