vb.net画图问题

LIXIAOGANG110217 2008-08-05 10:32:07
cpu占用率尽达100%。如何改进程序?谢谢老师们
Public Class Form1
Public f As Thread


Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
End
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
f = New Thread(AddressOf draw)
f.Start()
End Sub
Private Sub draw()
Dim x As Integer = 0
Dim y As Integer = 100
Dim b As Bitmap = New Bitmap(Me.picEMG.Width, Me.picEMG.Height, Imaging.PixelFormat.Format32bppArgb)
Dim G As Graphics = Graphics.FromImage(b)
G.Clear(Color.White)
G.TranslateTransform(0, picEMG.Height)‘picEMG是Picturebox的名字
Do
G.DrawLine(Pens.Blue, New Point(x, y), New Point(x + 2, -(y - 10)))

x += 2
y -= 10
If y = 0 Then
y = 100
End If
If x = Me.picEMG.Width Then
G.Clear(Color.White)
x = 0
End If
Me.picEMG.Image = b
'G.Dispose()

Loop
End Sub
End Class
...全文
468 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanlongwuhui 2008-08-06
  • 打赏
  • 举报
回复
ReceivedBytesThreshold没有设置成8192
LIXIAOGANG110217 2008-08-06
  • 打赏
  • 举报
回复
改成用SerialPort1_DataReceived接收数据了,咋还是100%的cpu占用率?
Public Class Form1
Public f As Thread


Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
End
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If SerialPort1.IsOpen Then
SerialPort1.Close()
End If
With SerialPort1
.PortName = "com1"
.BaudRate = 115200
.DataBits = 8
.ReadBufferSize = 8192 * 2

End With
SerialPort1.Open()

End Sub
Private Sub draw()
Static x As Integer = 0
'Dim y As Integer = 100
Dim b As Bitmap = New Bitmap(Me.picEMG.Width, Me.picEMG.Height, Imaging.PixelFormat.Format32bppArgb)
Dim G As Graphics = Graphics.FromImage(b)



G.Clear(Color.White)
G.TranslateTransform(0, picEMG.Height) 'picEMG是Picturebox的名字

G.DrawLine(Pens.Blue, New Point(x, SerialPort1.ReadByte), New Point(x + 2, -(SerialPort1.ReadByte)))


x += 2


If x >= Me.picEMG.Width Then

x = 0
End If
Me.picEMG.Image = b


End Sub

Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
If SerialPort1.BytesToRead >= 8192 Then
f = New Thread(AddressOf draw)
f.Start()

End If

End Sub
End Class
yanlongwuhui 2008-08-06
  • 打赏
  • 举报
回复
datareceived中的注意事项额可以参考下这里:
http://blog.csdn.net/CloneCenter/archive/2007/10/24/1841891.aspx
LIXIAOGANG110217 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 yanlongwuhui 的回复:]
在SerialPort1_DataReceived中读取数据
[/Quote]
是这样吗?
Private Sub serialport_datareceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

If SerialPort1.BytesToRead >= 8192 Then
Me.draw()
End If
End Sub
yanlongwuhui 2008-08-06
  • 打赏
  • 举报
回复
在SerialPort1_DataReceived中读取数据
LIXIAOGANG110217 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 yanlongwuhui 的回复:]
引用 18 楼 yanlongwuhui 的回复:
使用MSCOMM控件的话,通过设置RThreshold=每次接收的字节数来触发OnComm事件,然后在OnComm 事件中画线;使用serialport的话,通过设置ReceivedBytesThreshold=每次接收的字节数来触发DATARECEIVED事件,然后在DATARECEIVED事件中画线

你的窗口通讯是用什么实现的?
你现在用的是轮询的方式,也就是一直判断是否接收缓冲区中已经有8192个字节,达到8192个字节后进行读取并画图。这样你的…
[/Quote]
我用的是它自带的Serialport组件(Dim serialPort As New IO.Ports.SerialPort)
CloneCenter 2008-08-06
  • 打赏
  • 举报
回复
处理串口的DataReceived事件!根据得到的数据再重新绘制窗体。
另外,数据最后能保存到内存中,串口得到数据就只管塞到内存里面。重绘窗体时候,读取内存中的数据来画图。记住,在Form的Paint事件中处理画图即可!不需要使用什么死循环!
yanlongwuhui 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 yanlongwuhui 的回复:]
使用MSCOMM控件的话,通过设置RThreshold=每次接收的字节数来触发OnComm事件,然后在OnComm 事件中画线;使用serialport的话,通过设置ReceivedBytesThreshold=每次接收的字节数来触发DATARECEIVED事件,然后在DATARECEIVED事件中画线
[/Quote]
你的窗口通讯是用什么实现的?
你现在用的是轮询的方式,也就是一直判断是否接收缓冲区中已经有8192个字节,达到8192个字节后进行读取并画图。这样你的程序就一直存在检测缓冲区的字节数上了。而用事件驱动方式的话,设置好参数,一旦接收缓冲区达到8192个字节后,就会触发一下事件OnComm(或DATARECEIVED)。而你只要在事件里面做如下处理就可以了:
1.设置读取字节数为8192;
2.读取8192个字节;
3.画图;
等下个8192个字节到了,会自动再次触发。这样你的程序根本就不需要循环,CPU占用也不会那么大了。
LIXIAOGANG110217 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yanlongwuhui 的回复:]
串口通讯分事件驱动方式和查询方式两种方式,建议用事件驱动方式来做处理。例如4BYTE表示1个点,那就每接收4个字节触发一次,画一次。
[/Quote]
恩,现在我就是每接收8192个byte画一次。可是画完以后还是回到了判断串口缓存是否有8192个可读byte的死循环。我把画图过程注释掉了,只剩下判断串口缓存这过程。打开任务管理器,还是100%。所以,如何画图似乎没关系,这死循环才是病根儿。呵呵,咋整啊你说?不死循环的话,花一次不就不能再画了么?
LIXIAOGANG110217 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 djc7811 的回复:]
事件触发
[/Quote]
什么事件触发,触发什么。谢谢老师,呵呵
kouti 2008-08-06
  • 打赏
  • 举报
回复
关注中...
LIXIAOGANG110217 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 mzhao 的回复:]
把绘图过程写到picEmg.onPaint事件里面(不要创建Bitmap,直接在上面画),绘图内容访问一个Private变量取得,同时在检测输入的程序里更新Private变量,并调用picEmg.Refresh()
[/Quote]
如何不断触发picturebox的paint事件?
LIXIAOGANG110217 2008-08-06
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 yanlongwuhui 的回复:]
ReceivedBytesThreshold没有设置成8192
[/Quote]
刚才设置了,然后又运行了一下.结果还是100%的CPU占用率。
yanlongwuhui 2008-08-05
  • 打赏
  • 举报
回复
加sleep画慢应该没什么效果。
[转帖]Doevents函数详解
http://www.programfan.com/blog/article.asp?id=10027
cauhorse 2008-08-05
  • 打赏
  • 举报
回复
得画慢一点,不然每画一点,PictureBox就自动重绘一次,CPU占用率就一下上去了。
andyhere 2008-08-05
  • 打赏
  • 举报
回复
加个sleep(10),让它画慢一点
fairy4 2008-08-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 LIXIAOGANG110217 的回复:]
引用 2 楼 yanlongwuhui 的回复:
循环体中加一句application.DoEvents试试。另外你的循环没有退出条件?

嗯,我是让它一直画。因为我想做一个类似于示波器的东西,所以要一直监测信号。
[/Quote]
那就在do的後面加上Application.DoEvents()
然後判斷信號有沒有變更,沒有變更的話,就不需要重繪圖像,有變更才重繪。

我覺得這樣要一直循環的話,用單線程更好點。也方便控制些(可能我水平太菜,多線程好用,但是沒掌握好,使用起來還是有點麻煩)
fairy4 2008-08-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 LIXIAOGANG110217 的回复:]
引用 1 楼 wy24789 的回复:
加个sleep(10),让它画慢一点

提示未声明名称?
还有,具体加在那句话后面。谢谢老师。
[/Quote]
System.Threading.Thread.Sleep(10)
yanlongwuhui 2008-08-05
  • 打赏
  • 举报
回复
loop前面
fairy4 2008-08-05
  • 打赏
  • 举报
回复
我覺得不是畫圖速度的問題,是它一直在循環,沒有一刻停息。
就是陷入了死循環了,在循环体中判斷滿足條件就退出循環吧。
你就算執行一個空的死循環,你的CPU也是100%的。
加载更多回复(14)

16,717

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧