文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>如何实现非ui线程更新ui线程?

如何实现非ui线程更新ui线程?

时间:2011-04-19  来源:qiang.xu

1. 实现非ui线程更新ui线程的代码

2. 编码中出现的一个错误及探究 

<1>. 实现非ui线程更新ui线程 

 之前的基本做法是使用Invoke实现,这里采用的是 .net 4.0中的Task来实现,代码如下:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading.Tasks; using System.Threading; namespace WindowsFormsApplication1 {     public partial class Form1 : Form {         private readonly TaskScheduler m_syncContextScheduler = null;         public Form1() {             InitializeComponent();             base.Text = "Synchronization context task scheduler demo";             base.Visible = true;             base.Height = 100;             base.Width = 400;             // 属性m_syncContextScheduler需要在这里初始化              m_syncContextScheduler =                 TaskScheduler.FromCurrentSynchronizationContext();         }         private CancellationTokenSource cts;         private  TaskScheduler context = TaskScheduler.Current;                 // 计算         private Int32 Sum(CancellationToken token, Int32 n) {             Int32 sum = 0;             for (Int32 i = 1; i <= n; ++i) {                 // 出于演示目的,这里休眠一段时间                 Thread.Sleep(1000);                 sum += i;             }             return sum;         }         protected override void OnMouseClick(MouseEventArgs e) {             if (this.cts != null) {                 // 开始取消操作                 cts.Cancel();                 this.cts = null;             }             else {                 // 操作还没有开始,启动任务                 this.Text = "Operation running";                 this.cts = new CancellationTokenSource();                 var t = new Task<Int32>                 (                     () => Sum(cts.Token, 10),                     cts.Token                 );                 t.Start();                 // 如果该任务结束的话,启动新任务,更新ui线程                 t.ContinueWith(task => Text = "Result :" + t.Result,                     CancellationToken.None,                     TaskContinuationOptions.OnlyOnRanToCompletion,                     this.m_syncContextScheduler);                 // 如果是取消的话                  t.ContinueWith(task => Text = "Operation cancel",                     CancellationToken.None,                     TaskContinuationOptions.OnlyOnCanceled,                     this.m_syncContextScheduler);                 // 如果出现错误                 t.ContinueWith(task => this.Text = "Operation cancel",                     CancellationToken.None,                     TaskContinuationOptions.OnlyOnFaulted,                     this.m_syncContextScheduler);             }             base.OnMouseClick(e);         }     } }

<2>. 编码中出现的错误及探究 

 最初的代码将m_syncContextScheduler对象是通过下面的语句产生的:

private readonly TaskScheduler m_syncContextScheduler =

                TaskScheduler.FromCurrentSynchronizationContext(); 

debug时,产生如下错误:

 

通过异常信息可以看出这可能是当前初始化还为完成,那么这就引出c#中构造函数初始化和属性的初始化顺序的问题,通过调试或者是查看生成的il代码发现了问题所在,c#中首先执行

private TaskScheduler m_syncContextScheduler =
               TaskScheduler.FromCurrentSynchronizationContext(); 

此时环境还没有初始话完成。il中更加明显:

.method public hidebysig specialname rtspecialname          instance void  .ctor() cil managed {   // Code size       87 (0x57)   .maxstack  2   IL_0000:  ldarg.0   IL_0001:  ldnull   IL_0002:  stfld      class [System]System.ComponentModel.IContainer WindowsFormsApplication1.Form1::components   IL_0007:  ldarg.0   IL_0008:  call       class [mscorlib]System.Threading.Tasks.TaskScheduler [mscorlib]System.Threading.Tasks.TaskScheduler::FromCurrentSynchronizationContext()   IL_000d:  stfld      class [mscorlib]System.Threading.Tasks.TaskScheduler WindowsFormsApplication1.Form1::m_syncContextScheduler   IL_0012:  ldarg.0   IL_0013:  call       class [mscorlib]System.Threading.Tasks.TaskScheduler [mscorlib]System.Threading.Tasks.TaskScheduler::get_Current()   IL_0018:  stfld      class [mscorlib]System.Threading.Tasks.TaskScheduler WindowsFormsApplication1.Form1::context   IL_001d:  ldarg.0
// 初始化,调用form构造函数
  IL_001e:  call       instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()

 

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载