использовать Gmail API для отправки электронной почты из собственной учетной записи, не запрашивая согласия пользователя

Как я могу всегда ссылаться на мой метод ProgressForm.UPDATEME («новое сообщение прогресса») в любом другом методе в моем коде?

Нравится это:

public void UPDATEME(string MSG, bool finish = false)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(() => this.UPDATEME(MSG, finish)));
    }
    else
    {
        this.label1.Text = MSG;
        if (finish) { this.Close(); }
    }
}

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

It сначала сбивает с толку, так как это рекурсивный вызов. «Мясо» - это то, что Invoke() запускает все, что находится внутри него, в том же потоке, который создал элемент управления (сама форма в этом случае). Когда мы вводим метод во второй раз (из-за рекурсии), проверка возвращает false, и мы безопасно запускаем блок else в потоке пользовательского интерфейса.

Вы можете фактически избавиться от проверки (и рекурсии) всегда вызывая Invoke(), нужно ли это или нет:

public void UPDATEME(string MSG, bool finish = false)
{
    this.Invoke(new Action(() =>
    {
        this.label1.Text = MSG;
        if (finish) { this.Close(); }
    }));
}

Вот альтернативная версия, которая все еще проверяет, требуется ли Invoke(), но не использует рекурсию (менее запутанной, ve теперь вводил повторяющийся код):

public void UPDATEME(string MSG, bool finish = false)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action(() =>
        {
            this.label1.Text = MSG;
            if (finish) { this.Close(); }
        }));
    }
    else
    {
        this.label1.Text = MSG;
        if (finish) { this.Close(); }
    }
}

Для тех, которые являются «ориентированными на детали», вот подход / вариация (я использую MethodInvoker вместо Action), показывая один способ удалите дублирующий код выше:

public void UPDATEME(string MSG, bool finish = false)
{
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate
        {
            this.updater(MSG, finish);
        });
    }
    else
    {
        this.updater(MSG, finish);
    }
}

private void updater(string MSG, bool finish = false) // NOT thread safe, thus the private (don't call directly)
{
    this.label1.Text = MSG;
    if (finish) { this.Close(); }
}
0
задан Ammar Samater 19 January 2019 в 08:25
поделиться