Question

I'm developing a Windows Form app with C# and .NET Framework 4.0.

I'm using Task to run a long running task and I need to update UI with some log messages every time my task process a code.

There is a Queue processing that code, I need to show that a code has been processed.

private Task taskReadCodeAuto;
private delegate void RefreshTextBox();

private Queue CodesReceived;


public MainForm()
{
    InitializeComponent();

    logMessages = new List<string>();

    CodesReceived = new Queue();

    taskReadCodeAuto = new Task(() => ProcessCodesReceived());
}

private void ProcessCodesReceived()
{
    int result;
    try
    {
        while (CodesReceived.Count > 0)
        {
            string code = CodesReceived.Dequeue().ToString();
            InsertProfileMessage(DateTime.Now.ToString("HH:mm:ss.fff"), string.Format("Sending code {0} to ReadCodeAuto...", code));
            if (trzic == null)
            {
                result =
                    TRZIC.ReadCodeAuto(
                        ConnStringTextBox.Text,
                        byte.Parse(AggregationNumeric.Value.ToString()),
                        code);
            }
            else
            {
                result =
                    trzic.ReadCodeAuto(
                        byte.Parse(AggregationNumeric.Value.ToString()),
                        code);
            }

            InsertProfileMessage(DateTime.Now.ToString("HH:mm:ss.fff"), string.Format("Code sent {0}. Result: {1}", code, result));
        }
    }
    catch (Exception ex)
    {
        InsertProfileMessage(DateTime.Now.ToString("HH:mm:ss.fff"), "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        InsertProfileMessage(DateTime.Now.ToString("HH:mm:ss.fff"), "Error: " + ex.Message);
        InsertProfileMessage(DateTime.Now.ToString("HH:mm:ss.fff"), "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    }
    finally
    {
        InsertProfileMessage(DateTime.Now.ToString("HH:mm:ss.fff"), "END BG-WORKER");
    }
}

private void InsertProfileMessage(string time, string message)
{
    string profileString =
            string.Format("{0} - {1}", time, message);
    logMessages.Add(profileString);

    if (this.InvokeRequired)
    {
        RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults);
        Invoke(d);
    }
    else
    {
        RefreshTextBoxResults(profileString + "\n");
    }
}

private void RefreshTextBoxResults(string text)
{
    LogTextBox.AppendText(text);
}

My problem is that I don't know how to pass the text to show on LogTextBox using Invoke.

How can I do it?

Was it helpful?

Solution 2

You can add the parameters after the invoke:

        Action<string> d = RefreshTextBoxResults;
        this.Invoke(d, profileString + "\n");

Or invoke an action where the parameter is already included (which is this case is suitable regarding re usability)

Action d= () =>RefreshTextBoxResults(profileString + "\n");
if (this.InvokeRequired)
{
    Invoke(d);
}
else
{
    d();   
}

PS, if you want to use your RefreshTextBox delegate instead of an Action, the RefreshTextBox delegate should be altered to include a string parameter

OTHER TIPS

Use the overload of Invoke which takes an Object[] as a parameter for the arguments to be supplied to your method.

You would have to use the overload of Invoke which uses an array:

MSDN documentation

Pass the text value like below.

RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults);
Invoke(d,new object[] {“Pass value here”});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top