Silverlight雜談(1)- 跨線程訪問


 在Silverlight中,使用Thread,Timer,BackgrouWorker,ThreadPool可以實現多線程開發。但是隨之而來的問題是如何跨線程訪問資源呢?下面先以Timer計時器為例講解:

 示例

1、Timer.xaml

 1  < UserControl  x:Class ="ThreadDemo.Timer"
 2      xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3      xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
 4      xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
 5      xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6      mc:Ignorable ="d"
 7      d:DesignHeight ="300"  d:DesignWidth ="400" >
 8 
 9      < Grid  x:Name ="LayoutRoot"  Background ="White" >
10          < ScrollViewer >
11          < StackPanel  x:Name ="timerNum" >
12             
13          </ StackPanel >
14          </ ScrollViewer >
15      </ Grid >
16  </ UserControl >

 Timer.cs

 1  using System;
 2  using System.Collections.Generic;
 3  using System.Linq;
 4  using System.Net;
 5  using System.Windows;
 6  using System.Windows.Controls;
 7  using System.Windows.Documents;
 8  using System.Windows.Input;
 9  using System.Windows.Media;
10  using System.Windows.Media.Animation;
11  using System.Windows.Shapes;
12  using System.Threading;
13 
14  namespace ThreadDemo
15 {
16      public  partial  class Timer: UserControl
17     {
18          public Timer()
19         {
20             InitializeComponent();
21              /// 實例化一個Timer時間器
22              System.Threading.TimerTimer timer =  new System.Threading.TimerTimer( new TimerCallback(TimerProc));
23              /// 設定500毫秒后啟動,每隔1000毫秒執行一次
24              timer.Change( 5001000);
25         }
26          int flagnum;
27          public  void TimerProc( object state)
28         {
29                 flagnum++;
30                 TextBlock _temptext =  new TextBlock();
31                 _temptext.Text = flagnum.ToString(); 

32                 timerNum.Children.Add(_temptext);
33         
34         }
35     }
36 }

 

F5運行程序,Visual Studio報錯,跨線程訪問無效。

 


 

這里使用TimerCallback委托指定希望Timer執行的方法,但是此方法不能在計時器線程上執行,所以這里就存在一個跨線程訪問的問題。下面調整下代碼,計時器線程將該工作委托給與該UI線程關聯的Dispatcher。使用Dispatcher.BeginInvoke.

 2、Timer.cs

 1  using System;
 2  using System.Collections.Generic;
 3  using System.Linq;
 4  using System.Net;
 5  using System.Windows;
 6  using System.Windows.Controls;
 7  using System.Windows.Documents;
 8  using System.Windows.Input;
 9  using System.Windows.Media;
10  using System.Windows.Media.Animation;
11  using System.Windows.Shapes;
12  using System.Threading;
13 
14  namespace ThreadDemo
15 {
16      public  partial  class Timer: UserControl
17     {
18          public Timer()
19         {
20             InitializeComponent();
21              /// 實例化一個Timer時間器
22              System.Threading.Timer timer =  new System.Threading.Timer( new TimerCallback(TimerProc));
23              ///設定500毫秒后啟動,每隔1000毫秒執行一次
24              timer.Change(500, 1000);
25         }
26          int flagnum;
27          public  void TimerProc( object state)
28         {
29              /// 在計時器的線程上使用Dispather.BeginInvoke,將計時器線程上的工作委托給UI線程關聯的Dispatcher
30               this.Dispatcher.BeginInvoke( delegate
31             {
32                 flagnum++;
33                 TextBlock _temptext =  new TextBlock();
34                 _temptext.Text = flagnum.ToString();
35                 timerNum.Children.Add(_temptext);
36             });
37            
38         
39         }
40     }  41 }

 F5運行成功

 

 接下來,我們再用AsyncOperation來實現跨線程訪問。

3、Thread.xaml

 1  < UserControl  x:Class ="ThreadDemo.Thread"
 2      xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3      xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
 4      xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
 5      xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6      mc:Ignorable ="d"
 7      d:DesignHeight ="300"  d:DesignWidth ="400" >
 8     
 9      < Grid  x:Name ="LayoutRoot"  Background ="White" >
10          < ScrollViewer >
11              < StackPanel  x:Name ="timerNum" >
12 
13              </ StackPanel >
14          </ ScrollViewer >
15      </ Grid > 16  </ UserControl > 

 Thread.cs

 1  using System;
 2  using System.Collections.Generic;
 3  using System.Linq;
 4  using System.Net;
 5  using System.Windows;
 6  using System.Windows.Controls;
 7  using System.Windows.Documents;
 8  using System.Windows.Input;
 9  using System.Windows.Media;
10  using System.Windows.Media.Animation;
11  using System.Windows.Shapes;
12  using System.ComponentModel;
13 
14  namespace ThreadDemo
15 {
16      public  partial  class Thread : UserControl
17     {
18          private AsyncOperation async;
19         
20          public Thread()
21         {
22             InitializeComponent();
23             async = AsyncOperationManager.CreateOperation( null);
24             System.Threading.Thread thread =  new System.Threading.Thread(TimerProc);
25             thread.Start();
26         } 
27         
28          public  void TimerProc()
29         {
30            
31              async.Post(delegate
32             {
33             
34                 TextBlock _temptext =  new TextBlock();
35                 _temptext.Text = " 0 ";
36                 timerNum.Children.Add(_temptext);
37 
38             },  null);
39            
40         }
41 
42         
43     } 44 } 

ok.源碼下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM