Вы, вероятно, должны использовать async
и await
. По сути, две функции (и две кнопки) не имеют ничего общего друг с другом, при условии, что вы не блокируете GUI активно.
Например, вы можете сделать простой интерфейс с 4 элементами управления (я сделал это в WPF). Две кнопки, каждая из которых вызывает метод asyn c, и два текстовых блока, которые будут обновляться после метода asyn c.
Код WPF довольно прост. Обратите внимание на название событий щелчка.
<UniformGrid Columns="2">
<Button x:Name="UpdateSlow" Content="Wait 10 seconds" Click="UpdateSlow_Click" />
<Button x:Name="UpdateFast" Content="Wait 3 seconds" Click="UpdateFast_Click" />
<TextBlock x:Name="LongWaitTime" Text="Waiting for text" />
<TextBlock x:Name="ShortWaitTime" Text="Waiting for text" />
</UniformGrid>
И код, который содержит события щелчка.
private async void UpdateSlow_Click(object sender, RoutedEventArgs e)
{
await Task.Delay(10000);
LongWaitTime.Text = "I finished in 10 seconds";
}
private async void UpdateFast_Click(object sender, RoutedEventArgs e)
{
await Task.Delay(3000);
ShortWaitTime.Text = "I finished in 3 seconds";
}
Если вы нажмете кнопку «UpdateSlow», появится 10 секундная задержка, прежде чем текстовый блок "LongWaitTime" будет изменен. В то же время вы можете нажать кнопку «UpdateFast», которая обновит текстовый блок «ShortWaitTime» через 3 секунды. Скорее всего, окончание до истечения 10 секунд ожидания (в зависимости от того, когда вы, конечно, нажмете).
Надеюсь, что имеет смысл ...
Изменение текстового блока:
Я не могу точно определить, какова ваша цель, что затрудняет поиск действительно хорошего решения. Если это просто для удовольствия, приведенный ниже код должен работать. Однако я не уверен в возможных побочных эффектах доступа к одной и той же сборке строки двумя разными способами, поэтому я не рекомендовал бы это для производства.
<UniformGrid Columns="1">
<Button x:Name="AddStar" Content="Add star to text" Click="AddStar_Click" />
<TextBlock x:Name="Dots" Text="." Margin="20 0" VerticalAlignment="Center" FontSize="24" />
</UniformGrid>
public MainWindow()
{
InitializeComponent();
PrintDots();
}
public async void PrintDots()
{
// This will run forever, printing a dot every 0.2 seconds, clearing the string, when it reaches 50 characters.
while (true)
{
_sb.Append(".");
await Task.Delay(200);
if (_sb.Length == 50) { _sb.Clear(); }
Dots.Text = _sb.ToString();
}
}
private void AddStar_Click(object sender, RoutedEventArgs e)
{
// On click a star (asterix) will be appended to the string
_sb.Append("*");
Dots.Text = _sb.ToString();
}
Я решил оставить строку в StringBuilder , так как это должно быть намного лучше для производительности, а также для улучшения читаемости с помощью метода "Append".
Справедливое предупреждение:
Обычно async void
следует использовать только в пользовательских интерфейсах (например, при событиях нажатия кнопки). В большинстве других случаев это не очень хороший способ выполнения асинхронного программирования. Программа не сможет отслеживать прогресс метода после запуска. Это может привести к всевозможным забавным ситуациям, когда вы не знаете, какие методы сделаны, а какие нет. Вместо этого вы должны использовать async Task
, который можно вернуть и ожидать.