同时调用调用其他线程函数线程是不是盯着线程、盯着、函数

2023-09-03 07:01:46 作者:/

我使用一个线程显示进度窗口在执行耗时的操作(for循环)。之后的操作我想停止thread.but方法 ShowProgressDialog 不是called.I正在使用中的工作fine.below其它事件一样的方法是code。

 私人小组TSBRSToLoc_Click(发件人为System.Object的,E作为System.EventArgs)把手TSBRSToLoc.Click
    尝试

        如果不BWRRStoLoc.IsBusy然后
            DIM backgroundThred作为新主题(AddressOf ShowProgressDialog)
            backgroundThred.IsBackground = TRUE
            暗淡formProgree作为新ProgressForm
            backgroundThred.Start()
            DisableBtns(发件人)
            ProgressBarCompare.Value = 0
            lblProgStatus.Text =

            昏暗filesSize只要= 0
            对于指数为整数= 0要ObjlsViewCompare.Items.Count  -  1
                昏暗的文件,由于文件= ObjlsViewCompare.GetModelObject(指数)
                如果没有file.Status = MatchStatus.MisingOnRackSpace然后
                    filesSize = filesSize + file.SizeOnRackSpace
                结束如果
            下一个
            ProgressBarCompare.Maximum = filesSize
            formProgree.Close()
            backgroundThred.Abort()
            backgroundThred.Join()
            BWRRStoLoc.RunWorkerAsync()
        结束如果
    抓住EX为例外
        的MessageBox.show(ex.Message)
    结束尝试
结束小组
 

解决方案

有几个问题你code:

1:你几乎要叫 Thread.Abort的 - 它可能有未predictable效果的话,尤其是当一个线程终止另一个线程。 查看MSDN了解更多信息。

Thread的线程相关函数

要关闭线程的正确方法是使用某种消息的本身来告诉线程退出 - 设置一个静态变量(该线程周期性地检查),使用同步对象等 Thread.Abort的()是一大禁忌。

2:你有你的逻辑倒退:你有你的耗时在你的主线程操作(按钮单击事件处理表明,这是你的主UI线程),你想带你的进步从背景对话框主题。

这应该是周围的其他方法:你应该建立的所有数据,点击处理程序中的后台处理,显示进度对话框(假设它是无模式),然后揭开序幕后台线程,将做处理

在处理后台线程应该保持通知它的进步而进步的窗口,一旦完成,它也应该通知这一事实的进度窗口。

您需要通知您的UI线程任何时候,你必须正确MARSAL您调用正确的线程。这是因为任何UI元素只能从创建它的线程访问 - 例如,你不能没有封送处理呼叫建立从你的工作线程的标签控件的文本

您需要使用 InvokeRequired /的 的BeginInvoke() 封送。当调用的BeginInvoke()您会通过委托;像这样(对不起C#语法,我没那么熟悉VB.NET - 应该很容易移植这一点):

 私人无效SomeEventHandler(对象oSender,EventArgs的OE)
{
    如果(InvokeRequired)
    {
        MethodInvoker oDelegate =(MethodInvoker)代表
        {
            SomeEventHandler(oSender,OE);
        };

        的BeginInvoke(oDelegate);
        返回;
    }
    其他
    {
        //已经在正确的线程;访问UI控件在这里
    }
}
 

这一切都是因为控制处理许多他们的财产的更新通过邮件和这些消息必须同步发送,以正确的顺序。为确保这一点(不包括一些非常复杂的编码),唯一的办法就是在哪里线程运行一个消息泵同一线程创建的所有控件。

请参阅this问题的有关在一个线程比主UI线程等创建UI的详细信息。 (这是可能的,但你只是想这样做,如果你的真的,真的的需要这一点。这是相当罕见的。)

I am using a thread to display a progress window while performing a time consuming operation(the for loop).after that operation I want to stop the thread.but the method "ShowProgressDialog" is not being called.I am using the same approach in other event which is working fine.below is the code.

Private Sub TSBRSToLoc_Click(sender As System.Object, e As System.EventArgs) Handles TSBRSToLoc.Click
    Try

        If Not BWRRStoLoc.IsBusy Then
            Dim backgroundThred As New Thread(AddressOf ShowProgressDialog)
            backgroundThred.IsBackground = True
            'Dim formProgree As New ProgressForm
            backgroundThred.Start()
            DisableBtns(sender)
            ProgressBarCompare.Value = 0
            lblProgStatus.Text = ""

            Dim filesSize As Long = 0
            For index As Integer = 0 To ObjlsViewCompare.Items.Count - 1
                Dim file As File = ObjlsViewCompare.GetModelObject(index)
                If Not file.Status = MatchStatus.MisingOnRackSpace Then
                    filesSize = filesSize + file.SizeOnRackSpace
                End If
            Next
            ProgressBarCompare.Maximum = filesSize
            ' formProgree.Close()
            backgroundThred.Abort()
            backgroundThred.Join()
            BWRRStoLoc.RunWorkerAsync()
        End If
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

解决方案

There are several problems with your code:

1: You almost never want to call Thread.Abort - it may have unpredictable effects to do so, especially when one thread terminates another thread. See MSDN for more information.

The correct way to shut down a thread is to use some kind of message to tell the thread to exit by itself - set a static variable (that the thread checks periodically), use a synchronization object, etc. Thread.Abort() is a big no-no.

2: You have your logic backwards: you have your time-consuming operation on your main thread (the button click event handler shows that this is your main UI thread) and you're trying to show your progress dialog from a background thread.

It should be the other way around: you should set up all data for the background processing inside the click handler, show the progress dialog (assuming it's modeless) and then kick off the background thread that will do the processing.

During processing the background thread should keep notifying the progress window of its progress and once done, it should also notify the progress window of this fact.

Any time you need to notify your UI thread, you must properly marsal your call to the correct thread. This is because any UI elements may only be accessed from the thread that created it - for example, you cannot set the text of a label control from your worker thread without marshaling the call.

You need to use InvokeRequired / BeginInvoke() for marshaling. When calling BeginInvoke() you'll pass a delegate; something like this (sorry for the C# syntax, I'm not that familiar with VB.NET - should be easy to port this):

private void SomeEventHandler ( object oSender, EventArgs oE )
{
    if ( InvokeRequired )
    {
        MethodInvoker oDelegate = (MethodInvoker) delegate
        {
            SomeEventHandler ( oSender, oE );
        };

        BeginInvoke ( oDelegate );
        return;
    }
    else
    {
        // already on the correct thread; access UI controls here
    }
}

All this is because controls handle many of their property updates through messages and those messages must be delivered synchronously, in the correct order. The only way to ensure this (without some very complex coding) is to create all controls on the same thread where the thread runs a message pump.

See this question for more information about creating UI on a thread other than the main UI thread. (It's possible but you only want to do this if you really, really need that. That's fairly rare.)