C # проблема вызова потока - PullRequest
1 голос
/ 28 апреля 2011

Я пишу приложение формы в c #, и мне нужно иметь возможность изменять содержимое Rich Text Box из любого потока, я попытался использовать делегат и InvokeRequired , но делегат, который я сделал, по-прежнему выдает ошибку межпотокового вызова, и InvokeRequired завершает работу формы, не выдавая ошибку.Функция, которую мне нужно выполнить из любого потока:

    public static void updateSub(int what)
    {
        subDisplay.subBox.Text = tb[what];
    }

Делегат, которого я пытался использовать:

    public delegate void UpdateDelegateVoid(int what);
    static public UpdateDelegateVoid uSub = new UpdateDelegateVoid(updateSub);
    uSub(0);

Мой код InvokeRequired:

    public static void updateSub(int what)
    {
        if (subDisplay.subBox.InvokeRequired)
        {
            subDisplay.subBox.Invoke(new MethodInvoker(finish));
        }
        else
        {
            subDisplay.subBox.Text = tb[what];
        }
    }

Я не совсем уверен, почему приведенный выше код не работает.Спасибо!

Ответы [ 3 ]

3 голосов
/ 28 апреля 2011

Строго говоря, когда вы проверяете InvokeRequired и обнаруживаете, что это true, вы должны выполнить вызов для того же метода . Я не уверен, что это решит вашу конкретную проблему (мне нужно увидеть больше деталей об исключениях и код), но это то, что я имею в виду:

public static void updateSub(int what)
{
    if (subDisplay.subBox.InvokeRequired)
    {
        subDisplay.subBox.Invoke(new Action<int>(updateSub), what);
    }
    else
    {
        subDisplay.subBox.Text = tb[what];
    }
}

Если вы получаете "странное поведение", то убедитесь, что форма действительно создана в главном потоке приложения. В WinForms это не принудительно (как в WPF), поэтому вполне возможно, что поток, в котором была создана форма, на самом деле не является корневым потоком приложения.

2 голосов
/ 28 апреля 2011

Я в основном использую это, и оно отлично работает.Именно для этой цели вы и намерены.

public void UpdateSub(string message)
{
    subDisplay.subBox.Invoke((Action)delegate {
        subDisplay.subBox.Text = message;
    });
}

Надеюсь, это поможет вам или кому-то еще!

1 голос
/ 28 апреля 2011

Попробуйте это - когда вы вызываете тот же метод, если требуется вызов.

public void UpdateSub(string message)
{
    if (!subDisplay.subBox.InvokeRequired)
    {
        subDisplay.subBox.Text = message;
    }
    else
    {
        var d = new UpdateFormText(UpdateSub);
        Invoke(d, new object[] { message });
    }
}

Где UpdateFormText является делегатом

public delegate void UpdateFormText(string message);
...