科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件使用.NET多线程技术显示实时股票信息 2

使用.NET多线程技术显示实时股票信息 2

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

你通过StockSymbol属性把需要的股票编码传递给StockQuote类,并使用ChartControl属性设置图表更新。

作者:陶刚编译 来源:中国IT实验室 2008年6月9日

关键字: 信息 多线程 VB vb.net Windows

  • 评论
  • 分享微博
  • 分享邮件
你通过StockSymbol属性把需要的股票编码传递给StockQuote类,并使用ChartControl属性设置图表更新。InvokeWebService()方法在循环(示例中设置为10,000)中周期性地调用上面的Web服务。由于这个类会在一个单独的线程中执行,你必须非常小心以确保自己不会自动地更新某个Windows控件,因为Windows控件并不是线程安全的(thread-safe)。作为代替,你必须使用委托并调用自己希望更新的控件上的Invoke()方法。代码每秒钟调用Web服务一次,这是由Thread.Sleep(1000)语句设置的。

  为了启动线程用最新的股票信息更新图表,给"获取股票报价"按钮的点击(Click)事件增加下面的代码:

Private Sub btnGetStockQuote1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGetStockQuote1.Click
 Dim sq As New StockQuote
 sq.StockSymbol = cmbStocks1.SelectedItem
 sq.ChartControl = Chart1
 t1 = New Thread(AddressOf sq.InvokeWebService)
 t1.Start()
End Sub

  把调用该Web服务的代码打包为一个类的主要原因是Thread类构造函数只能接受一个ThreadStart委托(启动线程的方法的委托),不存在可以接受多个参数值的重载的Thread.Start()方法。因此,把多个参数传递到一个线程中的唯一途径是把调用的相关代码打包为一个类,接着你就可以通过这个类的参数来传递参数。

  按F5测试这段代码,选择一只股票并点击"获取股票报价"按钮。你现在可以移 动窗口了(即UI并没有被重复的Web服务调用锁死),并且同时可以看到图表一直在用最新的股票信息更新(图5所示)。

使用.NET多线程技术显示实时股票信息(2)
图5:测试该应用程序-当你选择某只股票编码并点击"获取股票报价"按钮的时候,重复调用Web服务的结果显示在图表中;但是由于该Web服务运行在后台线程上,调用它不会影响正常的UI操作。
显示多只股票的价格

  你已经看到了如何在保证应用程序的UI不停顿的情况下异步地调用Web服务了;但是,你还可以增强该应用程序来同时显示多个信息。

  在同一个窗体中,增加另一组控件(ChartFX、组合框和按钮)和标签、暂停、停止按钮(如图6所示)。

使用.NET多线程技术显示实时股票信息(3)
图6:增强的多股票窗体-此图显示了你需要添加到默认窗体上以同时显示两只股票图形的新控件。

  这个增强的示例同时显示了两个图形,还要显示用于显示第二个图形的线程的状态信息。

  添加第二个全局变量t2:

Dim t1, t2 As Thread

  示例项目使用计时器控件(Timer,在工具箱中)来显示第二个线程的状态信息。把计时器拖放到窗体上,并把它的Interval属性设置为500,这使该计时器的Tick事件每半秒钟(500毫秒)调用一次。Tick事件处理程序中的代码更新了标签控件lblThreadStatus中的线程状态信息:

Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
 lblThreadStatus.Text = "Thread state: " & _
t2.ThreadState.ToString
End Sub

  第二个图表也使用与第一个图表相同的初始化代码:

Private Sub Chart2_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Chart2.Load
 '在x轴上每5点显示时间
 Chart2.AxisX.Step = 5
 '每个点之间用5个象素分隔
 Chart2.AxisX.PixPerUnit = 5
 '使图表可以滚动
 Chart2.Scrollable = True
 '打开和关闭通讯管道-
 Chart2.OpenData(COD.Values, 1, COD.Unknown)
 Chart2.CloseData(COD.Values)
End Sub
 你点击第二个图表的"获取股票报价"按钮的时候,代码建立一个新的线程--同时激活计时器,这样窗体才能够显示线程的状态信息:

Private Sub btnGetStockQuote2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGetStockQuote2.Click
 Dim sq As New StockQuote
 sq.StockSymbol = cmbStocks2.SelectedItem
 sq.ChartControl = Chart2
 t2 = New Thread(AddressOf sq.InvokeWebService)
 t2.Start()

 '激活暂停和停止按钮
 btnPauseContinue.Enabled = True
 btnStop.Enabled = True
 '激活计时器控件
 Timer1.Enabled = True
End Sub

  按F5测试这两个图表(图7所示)。为每个图表选择一只股票,你将看到这两个图表同步显示。

使用.NET多线程技术显示实时股票信息(3)
图7:增强的两图表应用程序-增强的版本同时显示了两个图表。

  当第二个线程运行的时候,你可以注意到其状态在Running和WaitSleepJoin之间交替。这是因为某个线程要么在执行(Running),要么在睡眠(WaitSleepJoin)。当该线程被暂停的时候,它的状态是WaitSleepJoin、Suspended。当该线程被取消的时候,它的状态先是AbortRequested,接着变成了Stopped。

  如果要暂停该线程,需要首先检测运行中线程的状态,然后使用Suspend()方法。在暂停一个线程之后,你可以使用Resume()方法继续执行它。

Private Sub btnPauseContinue_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnPauseContinue.Click
' 如果线程处于睡眠和运行状态就挂起它
If t2.ThreadState = ThreadState.WaitSleepJoin _
 Or t2.ThreadState = ThreadState.Running Then
 t2.Suspend()
 btnPauseContinue.Text = "Continue"
Else
 ' 继续该线程
 t2.Resume()
 btnPauseContinue.Text = "Pause"
End If
End Sub

  停止线程则使用Abort()方法:

Private Sub btnStop_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnStop.Click
Try
 If Not t2.ThreadState = ThreadState.Stopped Then
  btnPauseContinue.Enabled = False
  btnStop.Enabled = False
  t2.Abort()
 End If
Catch ex As Exception
 MsgBox(ex.ToString)
End Try
End Sub

  通过运行示例项目,你会发现自己已经能够使用多线程技术建立应用程序,使应用程序在执行后台事务的时候,仍然保持响应。尽管本文的示例使用的是Web服务,但是相同的原则也可以应用于其它类型的后台事务。例如,你可以改变这个应用程序以读取外部设备(例如温度计或血压计监视设备)的数据。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章