Async в действии
От: WolfHound  
Дата: 20.05.10 13:24
Оценка: 112 (7)
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/ComputationExpressions/AsyncHttp
Я добавил пример того как можно использовать async.
Данный код демонстрирует асинхронный запрос к нескольким сайтам.

    private button1_Click (_sender : object,  _e : System.EventArgs) : void
    {
      responceBox.Text = "";
      def receive(url)
      {
        comp async
        {
          def url = url.Trim();
          when (url != "")
          {
            def time = System.Diagnostics.Stopwatch.StartNew();
            try
            {
              defcomp content = HttpGet(url).Start();//Start без параметров запускает вычисление в общем пуле потоков.
              //defcomp прирывает исполнение и освобождает поток до тех пор пока вычисление не будет завершено.
              //после чего исполнение возобновляется в том же контексте исполнения.
              responceBox.Text += $"$url\nTime: $(time.Elapsed)\nContent-Length: $(content.Length)\n\n\n\n";
            }
            catch
            {
              | ex is Exception =>
                responceBox.Text += $"$url\nTime: $(time.Elapsed)\nException: $(ex.Message)\n\n\n\n";
            }
          }
        }
      }
      foreach (url in urlBox.Lines)
        _ = receive(url).Start(guiCtx);//Запуск в контексте gui.
    }


Собственно запрос страници.
    private HttpGet(url : string) : Async[string]
    {
      comp async
      {
        def req = WebRequest.Create(url);
        using (defcomp resp = req.AsyncGetResponse())//Асинхронно дожидаемся ответа от сервера.
        using (stream = resp.GetResponseStream())//Далее идет синхронное чтение ответа.
        using (reader = StreamReader(stream))
          return reader.ReadToEnd();
      }
    }

Если он при исполнении выбросит исключение то при попытке получить разультат будет выброшено это же исключение.
Это можно проверить введя не существующий url или не правильный протокол например htttp.

Пример того на склько легко превратить стандартный в .NET паттерн асинхронных вычислений в Async.
    public static AsyncGetResponse(this req : WebRequest) : Async[WebResponse]
    {
      Async.FromBeginEnd
        ( req.BeginGetResponse(_, null)
        , req.EndGetResponse(_)
        );
    }


Методы расширения для асинхронного чтения и записи в поток.
    public AsyncRead(this stream : IO.Stream, arr : array[byte], offset : int, numBytes : int) : Async[int]
    {
      Async.FromBeginEnd
        ( stream.BeginRead(arr, offset, numBytes, _, null)
        , stream.EndRead(_)
        );
    }

    public AsyncWrite(this stream : IO.Stream, arr : array[byte], offset : int, numBytes : int) : Async[FakeVoid]
    {
      Async.FromBeginEnd
        ( stream.BeginWrite(arr, offset, numBytes, _, null)
        , stream.EndWrite(_)
        );
    }

Их использование можно посмотреть в тестах
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/ComputationExpressions/Test/AsyncTest.n
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.