Получить текст из TextBox из другого потока - PullRequest
0 голосов
/ 29 ноября 2018

Внутри класса у меня есть TextBox:

public class TextBoxAdapter {

    private System.Windows.Forms.TextBox textBox;

    //...some code that initializes the textBox...

    public string getTextFromBox() {
        if( textBox.InvokeRequired )
            return (string)textBox.Invoke( (Func<string>)delegate { return textBox.Text; } );
        else
            return textBox.Text;
    }
}

Для безопасного доступа к этому TextBox из другого потока, я бы хотел использовать механизм Invoke.Но функция getTextFromBox() завершается ошибкой в ​​строке, где используется Invoke().Я проверил это, поставив точку останова на этой строке и нажав F10 (шаг).Это терпит неудачу без исключения.Есть ли ошибка при моем способе вызова?

Редактировать

Почему мне нужно получить доступ к текстовому полю из другого потока?Я пытаюсь создать новую тему при каждом нажатии кнопки, чтобы предотвратить зависание моего интерфейса.Например, в окне входа пользователя в систему при нажатии кнопки входа в систему запускается новый поток, который уведомляет об этом и наблюдатель.Затем наблюдатель хочет прочитать значения текстового поля имени пользователя и пароля, чтобы проверить, является ли логинтри действительным.

Странная вещь в этом: запись в текстовое поле работает без каких-либо проблем.Код, который я использую:

        if ( textBox.InvokeRequired ) {
            MethodInvoker setText = new MethodInvoker( () => {
                textBox.Text = text;
            } );
            textBox.BeginInvoke( setText );
        }
        else {
            textBox.Text = text;
        }

1 Ответ

0 голосов
/ 03 декабря 2018

Вообще говоря, нет необходимости обращаться к элементам пользовательского интерфейса из рабочих потоков.

Вам следует изменить свой подход.Я предполагаю, что вы работаете в .NET Framework 4.5 или новее, поэтому для вас есть подходящий шаблон: TAP , более известный как async / await.

С этим шаблономВы не заботитесь о нитях.Framework заботится о них для вас.Ваша задача - сообщить компилятору, что нужно выполнить как асинхронное действие.

Просто пример - замените обработчик события Button на Click на что-то вроде этого:

async void LoginButton_Click(object sender, EventArgs e)
{
    // This runs on the UI thread
    string login = loginTextBox.Text;
    string password = pwdTextBox.Text;

    loginButton.Enabled = false;

    // This will be executed asynchronously, in your case - on a worker thread
    bool success = await Task.Run(() => myLoginProcessor.Login(login, password));

    // This runs again on the UI thread, so you can safely access your controls
    if (success)
    {
        labelResult.Text = "Successfully logged in.";
    }
    else
    {
        labelResult.Text = "Invalid credentials.";
    }

    loginButton.Enabled = true;
}
...