none
vb.net多线程问题 RRS feed

  • 问题

  • 最近做个一个vb.net的多线程的邮件群发工具,因为要发送的用户比较多,我在程序运行的开始启动一百个线程去群发邮件,并把每个线程的状态设置成start,当线程结束后将其状态设置为close,然后启动一个定时器定时去检测是否有现成结束。当有线程结束后,重新启动一个新的线程,不知道为什么开始的时候没事,当程序运行一段时间后,页面出现假死现象。如何进行一下优化????改掉页面假死的现象。
    2009年8月31日 2:19

答案

  • 在别的地方回过您  请不要自己动手写线城池   用system.threading.threadpool


    恭喜自己5星用户达成
    2009年8月31日 8:00
    版主
  • 楼主,您好,
    个人的两个体会,请参考:
    1、多线程往窗口上显示信息时,最好调用Invoke方法,不然会产生不稳定的因素。
    2、可以使用调试工具的高级方法,例如设置命中的次数,命中的条件(例如,写一个反应当前内存或cpu的方法,设个阀值,超过就命中。)
         也可以给每个线程付个名字。可以帮助调试,以找到真正的原因。
    2009年8月31日 9:29
  • 你好!

    我也比较推荐用线程池(Threadpool)。

    多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。但如果对多线程应用不当,会增加对单个任务的处理时间。

    线程池的作用主要是来管理线程,其技术正是关注如何缩短或调整线程时间的技术,从而提高服务器程序性能的。
    对于线程池更多的了解和一些例子,可以参考:
    http://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.aspx
    http://dev.csdn.net/article/45/45270.shtm

    希望对你有所帮助。

    (本回复中包含了第三方网站,微软无法控制和测试此类网站或者该网站提供的软件,因此,微软无法保证此类网站的质量和安全性。微软提醒您在下载软件或者打开网站之前确定您了解了该网站的安全性。)

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年9月1日 7:18

全部回复

  • 你好,多线程如果运用不当,可能造成线程阻塞,入对公共资源的访问、修改等,即便是运用锁,也可能由于代码不当造成死锁
    建议你采用25个线程,且对程序代码仔细考查一下
    Wenn ich dich hab’,gibt es nichts, was unerträglich ist.坚持不懈!http://hi.baidu.com/1987raymond
    2009年8月31日 2:36
    版主
  • 请用  system.threading.threadpool
    恭喜自己5星用户达成
    2009年8月31日 2:52
    版主
  • 最近做个一个vb.net的多线程的邮件群发工具,因为要发送的用户比较多,我在程序运行的开始启动多个线程去群发邮件,并把每个线程的状态设置成start,当线程结束后将其状态设置为close,然后启动一个定时器定时去检测是否有现成结束。当有线程结束后,重新启动一个新的线程,不知道为什么开始的时候没事,等程序运行时会页面出现短暂的停顿,而且随着运行时间的延长越来越慢,如何修改下面的代码??????
    具体代码如下:
    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            mSql.mSqlini()
                    qStr = "select top 240 id,email from table "
                    mSql.mSqlStr = qStr
                    mSql.mSqlSelect(errmsg, Rmd)
                    While Rmd.Read
                        If emailcount Mod 3 = 0 Then
                            If threadSendMail Is Nothing Then
                                ReDim threadSendMail(0)
                            Else
                                ReDim Preserve threadSendMail(threadSendMail.Length)
                            End If
                            threadSendMail(threadSendMail.Length - 1).mtablieid1 = mString.mTrim(Rmd("id"))
                            threadSendMail(threadSendMail.Length - 1).email = mString.mTrim(Rmd("email"))
                        ElseIf emailcount Mod 3 = 1 Then
                            threadSendMail(threadSendMail.Length - 1).mtablieid2 = mString.mTrim(Rmd("id"))
                            threadSendMail(threadSendMail.Length - 1).addccemail = mString.mTrim(Rmd("email"))
                        ElseIf emailcount Mod 3 = 2 Then
                            threadSendMail(threadSendMail.Length - 1).mtablieid3 = mString.mTrim(Rmd("id"))
                            threadSendMail(threadSendMail.Length - 1).addbccemail = mString.mTrim(Rmd("email"))
                            threadSendMail(threadSendMail.Length - 1).status = "start"
                            If threadSendMail(threadSendMail.Length - 1).email IsNot Nothing Then
                                ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf BackgroundSend), (threadSendMail.Length - 1))
                            End If
                                                  End If
                            emailcount += 1
                            count111 += 1
                    End While
                    Rmd.Close()

            mSql.mSqlClose()
            Timer1.Enabled = True
            Timer1.Interval = 15000
        End Sub
    Timer1中的代码如下:
     
          
            mSql.mSqlini()
            If count111 > 0 Then
                       For i = 0 To threadSendMail.Length - 1
                        If threadSendMail(i).status = "success" Or threadSendMail(i).status = "closed" Then
                            qStr = "select top 3 id,email from table"
                            mSql.mSqlStr = qStr
                            mSql.mSqlSelect(errmsg, Rmd)
                            While Rmd.Read
                                If emailcount1 Mod 3 = 0 Then
                                    If threadSendMail Is Nothing Then
                                        ReDim threadSendMail(0)
                                    Else
                                        ReDim Preserve threadSendMail(threadSendMail.Length)
                                    End If
                                    threadSendMail(i).mtablieid1 = mString.mTrim(Rmd("id"))
                                    threadSendMail(i).email = mString.mTrim(Rmd("email"))
                                ElseIf emailcount Mod 3 = 1 Then
                                    threadSendMail(i).mtablieid2 = mString.mTrim(Rmd("id"))
                                    threadSendMail(i).addccemail = mString.mTrim(Rmd("email"))
                                Else
                                    threadSendMail(i).mtablieid3 = mString.mTrim(Rmd("id"))
                                    threadSendMail(i).addbccemail = mString.mTrim(Rmd("email"))
                                    threadSendMail(i).status = "start"
                                    ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf BackgroundSend), (i))

                                 
                                End If
                                emailcount1 += 1
                            End While
                            Rmd.Close()
                            emailcount1 = 0
                        End If
                    Next
            mSql.mSqlClose()

     

    2009年8月31日 7:31
  • 在别的地方回过您  请不要自己动手写线城池   用system.threading.threadpool


    恭喜自己5星用户达成
    2009年8月31日 8:00
    版主
  • 我是用的system.threading.threadpool啊,前面已经引入了,不知道为什么程序会狂吃内存,
    2009年8月31日 8:14
  • 我是用的system.threading.threadpool啊,前面已经引入了,不知道为什么程序会狂吃内存,


    用 threading  pool 就完全不需要你自己控制任何线成了  也不需要你检查是否用完   你就全心全意往 ThreadPool.QueueUserWorkItem 里面扔吧
    一个线程默认需要1mb 堆栈空间


    恭喜自己5星用户达成
    2009年8月31日 8:29
    版主
  • 能不能给具体的修改一下,实在是被多线程搞的太头疼了
    2009年8月31日 8:37
  • 该你这个也很头疼阿  -0-
    恭喜自己5星用户达成
    2009年8月31日 9:03
    版主
  • 楼主,您好,
    个人的两个体会,请参考:
    1、多线程往窗口上显示信息时,最好调用Invoke方法,不然会产生不稳定的因素。
    2、可以使用调试工具的高级方法,例如设置命中的次数,命中的条件(例如,写一个反应当前内存或cpu的方法,设个阀值,超过就命中。)
         也可以给每个线程付个名字。可以帮助调试,以找到真正的原因。
    2009年8月31日 9:29
  • 你好!

    我也比较推荐用线程池(Threadpool)。

    多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。但如果对多线程应用不当,会增加对单个任务的处理时间。

    线程池的作用主要是来管理线程,其技术正是关注如何缩短或调整线程时间的技术,从而提高服务器程序性能的。
    对于线程池更多的了解和一些例子,可以参考:
    http://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.aspx
    http://dev.csdn.net/article/45/45270.shtm

    希望对你有所帮助。

    (本回复中包含了第三方网站,微软无法控制和测试此类网站或者该网站提供的软件,因此,微软无法保证此类网站的质量和安全性。微软提醒您在下载软件或者打开网站之前确定您了解了该网站的安全性。)

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2009年9月1日 7:18