Threading, let one thread know the others progress

2019-09-01 06:03发布

Ok, well I have been at it for a while now and I decided to just use threads. I am making a syntax highlighter but I keep getting terrible performance with the file sizes that it will usually be used for. So I made two forms, the first shows the file in plain text and has a button that says "openincolor" when you click that I start a new thread as such

    private void button1_Click(object sender, EventArgs e)
    {
        ColoringThread colorer = new ColoringThread(this.m_bruteView.Text);
        Thread theThread = new Thread(new ThreadStart(colorer.OpenColorWindow));
        theThread.Start();
    }

    public class ColoringThread
    {
        string text;
        public ColoringThread(string initText)
        {
            text = initText;
        }
        public void OpenColorWindow()
        {
            Form2 form2 = new Form2(text);
            form2.ShowDialog();
        }
    };

I want this form to send back a message each time it has complete say x lines of coloring. Then I will take that and figure out the progress and display it to the user.

How might I go about sending a message, or event(...? can I do that) to my first form to let it know of the others progress?

4条回答
一纸荒年 Trace。
2楼-- · 2019-09-01 06:35

You can pass an object as argument to the Thread.Start and share your data between the current thread and the initiating thread.


Here is a good example: How to share data between different threads In C# using AOP?


Or you can use BackgroundWorker which has ReportProgress

查看更多
祖国的老花朵
3楼-- · 2019-09-01 06:42

What you need is System.Windows.Threading.Dispatcher's BeginInvoke method. You can't directly modify a WPF object from your background thread, however you can dispatch a delegate to do that.

In your derived Window class object you have the Property Dispatcher, so you use it as follows:

Dispatcher.BeginInvoke(
  DispatcherPriority.Normal,
  (status) => { StatusTextBox.Text = status },
  thestatus
);

I'm sorry that I can't test that currently and I don't have the project here, where I did that. But I'm sure it will work, good luck ;)

Update: Oops, you're using Form's... I've written about WPF, sorry.

查看更多
仙女界的扛把子
4楼-- · 2019-09-01 06:49

One very simple way to do this is with BackgroundWorker. It already provides an event to report progress.

查看更多
我想做一个坏孩纸
5楼-- · 2019-09-01 06:57

How about something like this? This adds an event to the ColoringThread class which is subscribed to by the calling class.

private void button1_Click(object sender, EventArgs e) {
    ColoringThread colorer = new ColoringThread(this.m_bruteView.Text);
    colorer.HighlightProgressChanged += UpdateProgress;
    Thread theThread = new Thread(new ThreadStart(colorer.OpenColorWindow));
    theThread.Start();
}

private void UpdateProgress(int linesComplete) {
    // update progress bar here
}

public class ColoringThread
{
    string text;

    public delegate void HighlightEventHandler(int linesComplete);
    public event HighlightEventHandler HighlightProgressChanged;

    public ColoringThread(string initText) {
        text = initText;
    }

    public void OpenColorWindow() {
        Form2 form2 = new Form2(text);
        form2.ShowDialog();

        int linesColored = 0;
        foreach (String line in text.Split(Environment.NewLine)) {
            // colorize line here

            // raise event
            if (HighlightProgressChanged != null)
                HighlightProgressChanged(++linesColored);
        }
    }
};
查看更多
登录 后发表回答