Подождите, пока метод класса будет завершен C # - PullRequest
4 голосов
/ 16 июня 2011

Мне нужно скачать файл из источника Https.Я сделаю эту асинхронность следующим образом (пока работает):

void doChecksbeforDownload(){
//Do some Checks
   DownloadFileAsync();

}

void DownloadFileAsync(){
     ...
     ... 
     this.client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);
     this.client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
     this.client.UploadStringAsync(new Uri(url), "POST", PostParameter);
     ...
     ...
}

и вызову метод client_UploadStringCompleted (), когда закончим:

void client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
    {
       //Do Check here
    }

Пока все хорошо.Теперь я помещаю все это в класс «Функции» и вызываю метод следующим образом:

 Functions f = new Functions();
 f.doChecksbeforeDownload();

Я хочу, чтобы doChecksbeforeDownload () ожидал, пока clientUloadStringCompleted будет завершен.

Как мне сказать doChecksbeforeDownload ждать, пока вызов Async в DownloadFilesAsync не будет завершен и готов.

  1. Вызов doChecksbeforeDownload ()
  2. ChecksbeforeDownload () -> DownloadFileAsync ()
  3. ChecksbeforeDownload () -> Ожидания .......
  4. DownloadFileAsync () -> Complete & Ready
  5. ChecksbeforeDownload () -> возвращает FOOв основной класс

Есть ли лучшие практики / примеры для достижения этой цели?Я застрял в этой точке.

Заранее спасибо

Ханнес

Ответы [ 4 ]

5 голосов
/ 16 июня 2011

Вы захотите использовать объекты синхронизации, представленные в .NET.

Проверьте эту ссылку . Вот выдержка:

class BasicWaitHandle
{
  static EventWaitHandle _waitHandle = new AutoResetEvent (false);

  static void Main()
  {
    new Thread (Waiter).Start();
    Thread.Sleep (1000);                  // Pause for a second...
    _waitHandle.Set();                    // Wake up the Waiter.
  }

  static void Waiter()
  {
    Console.WriteLine ("Waiting...");
    _waitHandle.WaitOne();                // Wait for notification
    Console.WriteLine ("Notified");
  }
}

ПРИМЕЧАНИЕ. Будьте осторожны, делая события сброса статичными и т. Д. Тогда вы будете представлять проблемы безопасности потоков. Приведенный выше пример является статичным только для простоты.

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

Учтите, что вы можете ввести таймауты для вызова WaitOne () и т. Д.

1 голос
/ 16 июня 2011

Вам нужно найти какой-нибудь WaitHandle производный класс для выполнения задачи.

Я бы использовал ManualResetEvent , так как я думаю, что это один из самых простых.

0 голосов
/ 16 июня 2011

Вы можете создать переменную bool на уровне класса, например

bool isFinished = false;

Затем ваш асинхронный установит это значение в true, как только это будет сделано.

Затем выставьте переменную isFinished как общедоступное значение.

0 голосов
/ 16 июня 2011

Я просто плюю здесь, но как насчет этого:

In DownloadFileAsync() set a flag like DownloadInProgress

In doChecksbeforeDownload
  If DownloadInProgress Then set flag WaitingForDownloadCompletion
  Else Continue

In client_UploadStringCompleted()
  Set DownloadInProgress = false
  If WaitingForDownloadCompletion Then call doChecksbeforeDownload() 
...