繁体   English   中英

c#在主线程上使用thread.join时从子线程更新标签

[英]c# Update label from sub-thread when using thread.join on the main thread

我坚持尝试做一些看起来比我做起来容易的事情。

我想从一些辅助线程更新程序GUI上的状态标签(即IE进度)。

我不能使用同步调用,因为主线程在thread.Join();上被阻塞了。 重新启用接口输入/清除线程。 这会导致程序冻结。

我不想使用异步BeginInvoke,因为它会等到程序完成更新进度为止……违背了目的。

tl; dr-我知道为什么它行不通,但是我不确定如何解决它。

Button_Search_Click(object sender, EventArgs e)()
{
    DisableInput(); //Block input on start of function
    Cursor.Current = Cursors.WaitCursor; //set wait cursor

    //read combobox input
    string objectType = comboBox_Object.SelectedItem.ToString();
    string conditionType = comboBox_ConditionType.SelectedItem.ToString();
    string conditionOperator = comboBox_equals.SelectedItem.ToString();

    //create a list of worker threads
    List<Thread> workerThreads = new List<Thread>();

    //for each line in the textbox
    foreach (string searchText in textBox_SearchText.Lines)
    {
        if (String.IsNullOrWhiteSpace(searchText)) continue;

         //foreach line in a listbox
        foreach (String uri in Get_selected_sites())
        {
            string cred = (creddict[uri]);

            Thread thread = new Thread(() => Search(uri, cred, objectType, conditionType, conditionOperator, searchText));
            workerThreads.Add(thread);
            thread.Start(); //start main "work" function
        }

        // Wait for all the threads to finish
        foreach (Thread thread in workerThreads)
        {
            thread.Join();
        }
    }

    Displaydata();
    EnableInput(); //unlock input
    Cursor.Current = Cursors.Default; //set normal cursor
}

Search(uri, cred, objectType, conditionType, conditionOperator, searchText)
{
DoStuff();

//Update toolStripStatusLabel with progress stored in global int variable

//This doesn't work well because it waits until Thread.join() to update status label.
//BeginInvoke(new Action(() => Results_Count.Text = "Total Results = " + totalResults)); 

//This doesn't work at all because the main thread is blocked on Thread.Join()  -- it freezes the program
//statusStrip1.Invoke(new Action(() => Results_Count.Text = "Total Results = " + totalResults)); 

//This doesn't work/errors/crashes because the GUI is being modified by a thread other than main
//Results_Count.Text = "Total Results = " + totalResults;

DoMoreStuff();
}

非常感谢您提供的任何提示!

修正您的方法,使其看起来像这样:

async void Button_Search_Click(object sender, EventArgs e)()
{
    DisableInput(); //Block input on start of function
    Cursor.Current = Cursors.WaitCursor; //set wait cursor

    //read combobox input
    string objectType = comboBox_Object.SelectedItem.ToString();
    string conditionType = comboBox_ConditionType.SelectedItem.ToString();
    string conditionOperator = comboBox_equals.SelectedItem.ToString();

    //create a list of worker threads
    List<Task> workerTasks = new List<Task>();

    //for each line in the textbox
    foreach (string searchText in textBox_SearchText.Lines)
    {
        if (String.IsNullOrWhiteSpace(searchText)) continue;

         //foreach line in a listbox
        foreach (String uri in Get_selected_sites())
        {
            string cred = (creddict[uri]);

            workerTasks.Add(Task.Run(() => Search(uri, cred, objectType, conditionType, conditionOperator, searchText)));
        }

        await Task.WhenAll(workerTasks);
    }

    Displaydata();
    EnableInput(); //unlock input
    Cursor.Current = Cursors.Default; //set normal cursor
}

这样, Button_Search_Click()不会在任务运行时阻止UI线程,并且您可以使用常规的Invoke()或任何您喜欢的将更新发布到UI线程的机制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM