循环并将文本附加到StringBuilder问题

时间:2018-08-18 23:58:50

标签: c# winforms for-loop stringbuilder

尝试将一些循环中的文本添加到stringbuilder中时,我遇到了一个小问题。尝试了几件事之后,我认为我在此方面是正确的。

代码:

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    // STRING VALUE IT SO WE CAN REUSE //
    string action = e.Argument as string;

    // CONNECTION //
    if (action == "wraith_create_project")
    {

        // STRING BUILDER //
        StringBuilder sb = new StringBuilder();

        // VARS //
        var articleSource = "";

        // INVOKE - AVOID CROSS THREAD ERRORS //
        Invoke(new MethodInvoker(() => { articleSource = comboBoxArticleSources.Text; }));

        // TRY/CATCH //
        try
        {
            // INVOKE - AVOID CROSS THREAD ERRORS //
            Invoke(new MethodInvoker(() => { listBoxMain.Items.Add("[" + DateTime.Now + "] Creating project ... " + txtBoxProjectName.Text); }));

            // ARTICLE SOURCE //
            if (articleSource == "Internal Article Builder")
            {

                // VARS/CONSTANTS //
                var separator             = Environment.NewLine;
                const string gsaSeparator = "\x01";

                // WHICH SPINNER TO USE //
                if (chkBoxInternalSpinner.Checked) {

                    // LOOP //
                    var title = "";
                    var body  = "";
                    var hash  = "";
                    //var gsaArticleInfo = "";

                    for (int x = 0; x <= 5; x++ ) {

                        // EVERY LOOP REQUESTS AN ARTICLE //
                        var requestArticles = Helpers.getArticleTitleAndBodyInternalSpinner("https://www.wraithseo.com/api.php?articleBuilder=1&q=" + txtBoxScrapeKeyword.Text.Replace(" ", "_"));

                        title = Helpers.internalSpinner(requestArticles.Item1); // SEND TO INTERNAL SPINNER FOR SPINNING ...
                        body  = Helpers.internalSpinner(requestArticles.Item2); // SEND TO INTERNAL SPINNER FOR SPINNING ...
                        hash  = To32BitFnv1aHash(body).ToString("X8");

                        Invoke(new MethodInvoker(() =>
                        {
                            listBoxMain.Items.Add("[" + DateTime.Now + "] Returned article ... " + requestArticles.Item1);
                            listBoxMain.Items.Add("[" + DateTime.Now + "] Spun the article ... " + title);
                        }));

                        // ENCODE WITH THE GSA SEPERATOR BETWEEN EACH FIELD //
                        var gsaArticleInfo = title + gsaSeparator + "%first_paragraph-article%"  + gsaSeparator + body + gsaSeparator + hash;

                        // ADD TO THE RICHTEXTBOX ALL FIELDS FROM ABOVE //
                        var richTextBoxText = string.Join(separator, gsaArticleInfo);

                        // APPEND FIELDS TO THE STRINGBUILDER //
                        sb.Append(richTextBoxText);

                    }

                    // INVOKE - AVOID CROSS THREAD ERRORS //
                    Invoke(new MethodInvoker(() => { richTxtBoxArticle.Text = sb.ToString(); }));

                } 

            } else if (articleSource == "") {
                   // RESERVED FOR ADDITIONAL SOURCES //                    
            }

        } catch (Exception ex) {
            Helpers.returnMessage(ex.ToString());
        }
    }
}

我在这里所做的是向服务器发送请求,该服务器返回一则文章大小的文本,然后旋转文本并尝试在richTextBox中显示它,我注意到,与其添加每篇文章到richTextBox,它被同一篇文章覆盖,我想通过使用stringbuilder在每个循环上将文章附加到它之后,我可以在循环外显示它,但它似乎总是被覆盖,而不是添加5篇文章(我已设置的最大值)

任何帮助将不胜感激。

更新的代码:

    private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
    {

        string action = e.Argument as string;

        if (action == "wraith_create_project")
        {

            StringBuilder sb = new StringBuilder();

            var separator = Environment.NewLine;
            const string gsaSeparator = "\x01";

            var articleSource = "";
            var title = "";
            var body = "";
            var hash = "";
            var gsaArticleInfo = "";
            var richTextBoxText = "";

            // TEST //
            List<string> gsaStuff = new List<string>();
            // TEST //

            Invoke(new MethodInvoker(() => { articleSource = comboBoxArticleSources.Text; }));

            try
            {
                Invoke(new MethodInvoker(() => { listBoxMain.Items.Add("[" + DateTime.Now + "] Creating project ... " + txtBoxProjectName.Text); }));

                if (articleSource == "Internal Article Builder")
                {

                    if (chkBoxInternalSpinner.Checked) {

                        for (int x = 0; x <= 5; x++ ) {

                            // EVERY LOOP REQUESTS AN ARTICLE WHICH IS RETURNED AT RAND() //
                            var requestArticles = Helpers.getArticleTitleAndBodyInternalSpinner("https://www.wraithseo.com/api.php?articleBuilder=1&q=" + txtBoxScrapeKeyword.Text.Replace(" ", "_"));

                            title = Helpers.internalSpinner(requestArticles.Item1); // SEND TO INTERNAL SPINNER FOR SPINNING ...
                            body  = Helpers.internalSpinner(requestArticles.Item2); // SEND TO INTERNAL SPINNER FOR SPINNING ...
                            hash  = To32BitFnv1aHash(body).ToString("X8");

                            Invoke(new MethodInvoker(() =>
                            {
                                listBoxMain.Items.Add("[" + DateTime.Now + "] Returned article ... " + requestArticles.Item1);
                                listBoxMain.Items.Add("[" + DateTime.Now + "] Spun the article ... " + title);
                            }));

                            // ENCODE WITH THE GSA SEPERATOR BETWEEN EACH FIELD //
                            gsaArticleInfo = title + gsaSeparator + "%first_paragraph-article%"  + gsaSeparator + body + gsaSeparator + hash;

                            // ADD TO THE RICHTEXTBOX ALL FIELDS FROM ABOVE //
                            richTextBoxText = string.Join(separator, gsaArticleInfo);

                            // APPEND FIELDS TO THE STRINGBUILDER //
                            sb.Append(string.Join(separator, gsaArticleInfo));

                            gsaStuff.Add(richTextBoxText);

                            // INVOKE - AVOID CROSS THREAD ERRORS //
                            Invoke(new MethodInvoker(() => { richTxtBoxArticle.AppendText(richTextBoxText); }));
                            Invoke(new MethodInvoker(() => { richTxtBoxArticle.Lines = gsaStuff.ToArray(); }));

                        } // End for loop.

                        Invoke(new MethodInvoker(() => { richTxtBoxArticle.Lines = gsaStuff.ToArray(); }));
                        //Helpers.returnMessage("SB Contents: > " + sb.ToString());

                    } // End checkbox.

                } else if (articleSource == "") {
                       // RESERVED FOR ADDITIONAL SOURCES //                    
                }

            } catch (Exception ex) {
                Helpers.returnMessage(ex.ToString());
            }

        }
    }

1 个答案:

答案 0 :(得分:0)

之所以发生这种情况,是因为您实际上是从另一个线程快速调用UI线程。文本框根本跟不上。

这里的解决方案是使用BackgroundWorker.ReportProgress方法,并将字符串从工作线程传递回UI线程。您可以从表单中处理工作程序的ProgressChanged事件,并在那里更新控件。

希望对您有帮助。