2014-08-20 3 views
1

У меня многопоточное приложение C#, в котором нажатие кнопки (Button homeBut) запускает новый поток, который выполняет данный метод. При щелчке, я отключить кнопку и запустить поток.C# Call Method On Return

Чтобы повторно включить кнопку, я в настоящее время сделать это в конце метода:

if (InvokeRequired)//if accessing from different thread 
    { 
     this.Invoke(new Action<Button>(enableButton), new object[] { homeBut }); 
    } 

Есть несколько мест, из которых можно вернуть метод, и я надеялся, чтобы избежать копирования и вставки этого кода фрагмент в 4 разных местах, чтобы кнопка всегда была включена.

Есть ли способ, которым я могу выполнить такой блок кода всякий раз, когда метод возвращается, так что я только пишу его один раз?

ответ

3

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

Ну, как насчет метода, это обычно то, за что они предназначены.

void EnableHomeButton() 
{ 
    if (InvokeRequired)//if accessing from different thread 
    { 
     this.Invoke(new Action<Button>(enableButton), new object[] { homeBut }); 
    } 
    else 
    { 
     enableButton(homeBut); 
    } 
} 

Также не создавайте свои темы. Начало Tasks.

DisableButton(); 
Task.Factory.StartNew(DoWhatEver).ContinueWith(EnableHomeButton); 
+0

Thanks weston; метод ContinueWith - именно то, что я искал. Есть ли недостаток в использовании задачи вместо потока? – Derek

+1

Нет, потому что задача выполняется на одном из нескольких потоков фона из пула потоков, но поскольку это потоки, которые используются повторно, и вам не нужно создавать их, чтобы они были быстрее. (Запуск потока - довольно дорогое дело). – weston

2

Вот три способа:

  1. Создать объект, который делает то, что вам нужно сделать, когда он выходит из области видимости (например, с using pattern).

  2. Измените функцию только на один обратный путь.

  3. Вызвать функцию из внешней функции, которая делает все, что вам нужно, после того, как функция вернется.

  4. try/finally.

+0

деструктор? Что вы имеете в виду? – weston

+0

В этом случае 2 не очень хороший вариант. Я надеялся избежать варианта 3. Можете ли вы уточнить вариант 1? – Derek

+0

Надеюсь, он не имеет в виду фактических деструкторов. Http://msdn.microsoft.com/en-GB/library/66x5fx1b.aspx не пытается их использовать. – weston

0

Я не очень понимаю, что вы вызываете нить. Пожалуйста, укажите. Если функция/thread вызывается с помощью BeginInvoke, тогда вы можете указать метод «асинхронного обратного вызова», который будет запущен в конце потока.

Ниже приводится рабочий пример кода

class Program 
{ 
    static void Main(string[] args) 
    { 
     Del del = new Del(Notify); 
     del.BeginInvoke("abc", callback, new object { }); 
    } 

    private static void callback(IAsyncResult ar) 
    { 
     if (InvokeRequired)//if accessing from different thread 
     { 
     this.Invoke(new Action<Button>(enableButton), new object[] { homeBut }); 
     } 
     Console.Write("Callback Triggerd. Thread Completed"); 
    } 
    // Declare a delegate. 
    delegate void Del(string str); 

    // Declare a method with the same signature as the delegate. 
    static void Notify(string name) 
    { 
     Console.WriteLine("Notification received for: {0}", name); 
    } 
} 
+0

Я использую событие button_clicked, чтобы сначала отключить кнопку: 'homeBut.Enabled = false'. Затем я запускаю новый поток, ориентированный на метод: «Thread thr = new Thread (homeAxes)». Когда 'homeAxes()' возвращается, мне нужно снова включить кнопку. – Derek

+0

@Derek, есть ли возможность, что вы можете использовать делегат, тогда ваш обратный вызов можно легко обрабатывать, как описано выше. –

1

Другим решением, которое вы могли бы рассмотреть это:

private async void SomeButtonClicked(object sender, EventArgs e) 
{ 
    try 
    { 
     DisableButton(); 
     await ALongRunningTaskAsync(); 
    } 
    finally 
    {   
     EnableButton(); 
    } 
} 

С помощью асинхр/ждать вы знаете, программа переключается обратно в исходный поток, в этом случае поток пользовательского интерфейса, и даже пытаясь угадать наконец, сработает. Просто убедитесь, что ALongRunningTaskAsync возвращает задачу (или задачу)