The interface freezes while loading an event

Asked

Viewed 45 times

2

I did an event with a lot of time consuming operations and I need to keep describing the operations in a Richtextbox, so I use Richtextbox.Appendtext("Something"), only what I wrote only appears when the method finishes everything. I did an extension method for Richtextbox and tried to leave it as async, but I am very inexperienced with this part yet and got a lot of errors.

The first mistake ever made here:

using System;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Dirlididi_Windows
{
    public static class RichTextBoxExtensionClass
    {
        public static async Task AppendText(this RichTextBox box, string text, Color color)
        {
            box.SelectionStart = box.TextLength;
            box.SelectionLength = 0;

            box.SelectionColor = color;
            box.AppendText(text);
            box.SelectionColor = box.ForeColor;
        }
    }
}

Now the other part:

private void webclient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                if (e.Error == null)
                {
                    Problem problem = Newtonsoft.Json.JsonConvert.DeserializeObject<Problem>(e.Result);

                    richTextBoxResult.AppendText("Compilando...\n");

                    ProcessStartInfo processStartInfoCompile = new ProcessStartInfo(javaJdkPath + "\\javac.exe", "\"" + labelFilePath.Text + '"');
                    processStartInfoCompile.WindowStyle = ProcessWindowStyle.Hidden;
                    processStartInfoCompile.CreateNoWindow = true;
                    processStartInfoCompile.UseShellExecute = false;
                    processStartInfoCompile.RedirectStandardError = true;

                    Process processCompile = Process.Start(processStartInfoCompile);
                    processCompile.WaitForExit();

                    string error = processCompile.StandardError.ReadToEnd();
                    if (error == "")
                    {
                        richTextBoxResult.AppendText("Sucesso na compilação!\n\n", Color.Green);

                        List<List<string>> listOfResultsAndKeys = new List<List<string>>();

                        bool haveError = false;

                        for (int i = 0; i < problem.tests.Count; i++)
                        {
                            richTextBoxResult.AppendText(string.Format("Teste #{0}: \n", i));

                            if (problem.tests[i].publish)
                            {
                                ProcessStartInfo processStartInfoExecute = new ProcessStartInfo();
                                processStartInfoExecute.WorkingDirectory = labelFilePath.Text.Remove(labelFilePath.Text.LastIndexOf('\\'));
                                processStartInfoExecute.FileName = "java";
                                string fileName = Path.GetFileName(labelFilePath.Text);
                                processStartInfoExecute.Arguments = fileName.Remove(fileName.LastIndexOf('.'));
                                processStartInfoExecute.WindowStyle = ProcessWindowStyle.Hidden;
                                processStartInfoExecute.CreateNoWindow = true;
                                processStartInfoExecute.UseShellExecute = false;
                                processStartInfoExecute.RedirectStandardInput = true;
                                processStartInfoExecute.RedirectStandardOutput = true;
                                processStartInfoExecute.RedirectStandardError = true;

                                Process processExecute = Process.Start(processStartInfoExecute);
                                processExecute.StandardInput.WriteLine(problem.tests[i].input);
                                bool tle = processExecute.WaitForExit(2000);

                                error = processExecute.StandardError.ReadToEnd();
                                string output = processExecute.StandardOutput.ReadToEnd();

                                if (!tle)
                                {
                                    richTextBoxResult.AppendText("TLE (2000)!\n\n", Color.Blue);
                                }
                                else if (error != "")
                                {
                                    richTextBoxResult.AppendText(error + "\n\n", Color.Red);
                                    haveError = true;
                                }
                                else if (output.Replace("\r\n", "\n") != problem.tests[i].output + "\n")
                                {
                                    List<string> miniList = new List<string>(2);
                                    miniList.AddRange(new string[] { problem.tests[i].key, output.Replace("\r\n", "\n") });
                                    listOfResultsAndKeys.Add(miniList);

                                    richTextBoxResult.AppendText("Diferenças na saída...\n", Color.Red);

                                    StringReader stringReader0 = new StringReader(output);
                                    StringReader stringReader1 = new StringReader(problem.tests[i].output);

                                    string line0 = "", line1 = "";
                                    while (((line0 = stringReader0.ReadLine()) != null) | ((line1 = stringReader1.ReadLine()) != null))
                                    {
                                        if (line0 != null)
                                        {
                                            richTextBoxResult.AppendText("(saída)    > " + line0 + "\n");
                                        }
                                        if (line1 != null)
                                        {
                                            richTextBoxResult.AppendText("(esperado) > " + line1 + "\n");
                                        }
                                        richTextBoxResult.AppendText("\n");
                                    }
                                    richTextBoxResult.AppendText("\n");
                                }
                                else
                                {
                                    List<string> miniList = new List<string>(2);
                                    miniList.AddRange(new string[] { problem.tests[i].key, output.Replace("\r\n", "\n") });
                                    listOfResultsAndKeys.Add(miniList);

                                    richTextBoxResult.AppendText("OK!\n\n", Color.Green);
                                }
                            }
                            else
                            {
                                richTextBoxResult.AppendText("Teste não publicado. Ignore.\n\n");
                            }
                        }

                        if (!haveError)
                        {
                            richTextBoxResult.AppendText("Fim dos testes locais.\n\nComeçando a enviar pro servidor e ver o que ele retorna...\n\n");

                            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(dirlididiApiBaseAddress + "code/" + problem.key);
                            request.Method = "POST";

                            Submit submit = new Submit();
                            submit.tests = listOfResultsAndKeys;
                            submit.key = problem.key;
                            submit.token = textBoxToken.Text;
                            submit.code = File.ReadAllText(labelFilePath.Text);

                            byte[] data = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(submit));
                            request.ContentLength = data.Length;

                            using (var stream = request.GetRequestStream())
                            {
                                stream.Write(data, 0, data.Length);
                            }

                            try
                            {
                                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                                string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

                                Result result = Newtonsoft.Json.JsonConvert.DeserializeObject<Result>(responseString);

                                bool haveErrorOnServer = false;
                                for (int i = 0; i < result.result.Length; i++)
                                {
                                    if (result.result[i] != '.')
                                    {
                                        haveError = true;
                                    }
                                }

                                if (!haveErrorOnServer)
                                {
                                    richTextBoxResult.AppendText("Julgamento do servidor: " + result.result + '\n', Color.Green);
                                }
                                else
                                {
                                    richTextBoxResult.AppendText("Julgamento do servidor: " + result.result + '\n', Color.Red);
                                }

                                buttonSubmit.Enabled = true;
                            }
                            catch (Exception ex)
                            {
                                richTextBoxResult.AppendText("O servidor retornou algum erro:\n" + ex.Message + '\n');

                                buttonSubmit.Enabled = true;
                            }
                        }
                        else
                        {
                            richTextBoxResult.AppendText("Como houve erro, não será enviado ao servidor.\n\n");

                            buttonSubmit.Enabled = true;
                        }
                    }
                    else
                    {
                        richTextBoxResult.AppendText("Erro na hora de compilar...\n" + error + '\n');

                        buttonSubmit.Enabled = true;
                    }
                }
                else
                {
                    richTextBoxResult.AppendText(e.Error.Message + '\n');
                    buttonSubmit.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                richTextBoxResult.AppendText("Houve algum erro durante toda a operação: " + ex.Message + '\n');

                buttonSubmit.Enabled = true;
            }
        }
  • You can put the code you tried?

  • I will put and try to put summarized.

  • The other code is not great no, and we will need it to direct a response. You can put it too?

  • Okay, I put the code before trying to use await in the methods, because I understood that was what you had requested

  • Crazy thing. You call Java to compile a code, then send it to a server and update the Windows on screen?

  • 1

    It’s a program to test some codes, ignore that.

Show 1 more comment

1 answer

2


About calling a Process in an asynchronous way, you will have to use a code like this:

public static async Task<int> RunProcessAsync(string fileName, string args)
{
    using (var process = new Process
    {
        StartInfo =
        {
            FileName = fileName, Arguments = args,
            UseShellExecute = false, CreateNoWindow = true,
            RedirectStandardOutput = true, RedirectStandardError = true
        },
        EnableRaisingEvents = true
    })
    {
        return await RunProcessAsync(process).ConfigureAwait(false);
    }
}    

private static Task<int> RunProcessAsync(Process process)
{
    var tcs = new TaskCompletionSource<int>();

    process.Exited += (s, ea) => tcs.SetResult(process.ExitCode);
    process.OutputDataReceived += (s, ea) => richTextBoxResult.AppendText(ea.Data, Color.Green);
    process.ErrorDataReceived += (s, ea) => richTextBoxResult.AppendText("Erro: " + ea.Data, Color.Red);

    bool started = process.Start();
    if (!started)
    {
        throw new InvalidOperationException("Processo não pode ser iniciado: " + process);
    }

    process.BeginOutputReadLine();
    process.BeginErrorReadLine();

    return tcs.Task;
}

Make whatever modifications you think are necessary to invoke your methods. The call should look something like this:

await this.RunProcessAsync(javaJdkPath + "\\javac.exe", "\"" + labelFilePath.Text + '"', null);

Repeat this for the other steps and the procedure should occur asynchronously. If you need more help, ask other questions with more specific excerpts.

  • Thanks! Gave a small error there where richTextBox is.

  • Feel free to edit anything. I have not tested this code.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.