WCF - AsyncPattern Performance - PullRequest
       0

WCF - AsyncPattern Performance

1 голос
/ 01 ноября 2011

Я написал следующую службу WCF, которая реализует два метода.Они оба делают одно и то же, но один из них является синхронным, а другой - асинхронным.Результат нагрузочного теста (с использованием Pylot ) разочаровывает.Я получаю почти одинаковую пропускную способность от синхронизации и асинхронной версии метода (см. Номера производительности ниже).

Я развернул службу на реальном сайте IIS (не Кассини), и я вижу ту же схему.Что я делаю неправильно?У меня сложилось впечатление, что с помощью WCF AsyncPattern я смогу увеличить нагрузку.Правильно ли мое предположение?Я что-то не так делаю?

Спасибо!

[ServiceContract]
public class Service1
{
    // Synchronous version
    [WebGet(UriTemplate = "/sync")]
    public List<SampleItem> GetSamples()
    {
        return this.LongRunningMethod();
    }

    // Asynchronous version - Begin
    [WebGet(UriTemplate = "/async")]
   [OperationContract(AsyncPattern = true)]
    public IAsyncResult BeginGetSampleAsync(AsyncCallback callback, object state)
    {
        var task = Task<List<SampleItem>>.Factory.StartNew(() => this.LongRunningMethod());

        Func<List<SampleItem>> getSampleItems = () => this.LongRunningMethod();

        return getSampleItems.BeginInvoke(callback, state);
    }

    // Asynchronous version - End
    public List<SampleItem> EndGetSampleAsync(IAsyncResult result)
    {
        AsyncResult typedAsyncResult = (AsyncResult)result;
        Func<List<SampleItem>> func = (Func<List<SampleItem>>)typedAsyncResult.AsyncDelegate;

        return func.EndInvoke(result);
    }

    private List<SampleItem> LongRunningMethod()
    {
        // Simulate some load... I/O operations
        Thread.Sleep(500);

        return new List<SampleItem>() { new SampleItem() { Id = 1, StringValue = "Hello" } };
    } 

Ниже приведен перф.цифры.

Performance Numbers
-------------------------------------------------
Test parameters:
  number of agents:          500
  test duration in seconds:  60
  rampup in seconds:         0
  interval in milliseconds:  0
  test case xml:             **syncTestCase.xml**
  log messages:              False


Started agent 500

All agents running...


[################100%##################]  60s/60s

Requests:  3836
Errors: 0
Avg Response Time:  7.286
Avg Throughput:  63.92
Current Throughput:  70
Bytes Received:  852036

-------------------------------------------------   

Test parameters:
  number of agents:          500
  test duration in seconds:  60
  rampup in seconds:         0
  interval in milliseconds:  0
  test case xml:             **asyncTestCase.xml**
  log messages:              False


Started agent 500

All agents running...


[################100%##################]  60s/60s

Requests:  3884
Errors: 0
Avg Response Time:  7.176
Avg Throughput:  64.66
Current Throughput:  620
Bytes Received:  862248

-------------------------------------------------

1 Ответ

3 голосов
/ 01 ноября 2011

Ваш тест очень искусственный. Асинхронное программирование лучше всего подходит для операций с большим количеством операций ввода-вывода , которые не должны требовать ожидания на работающем потоке (скорее они должны основываться на портах завершения ввода-вывода или аналогичных). Ваш тест использует потоки пула потоков (BeginInvoke / EndInvoke) и блокирует их (Thread.Sleep), что почти гарантирует, что вы в конечном итоге будете делать хуже , чем в случае синхронизации, когда вы не едите все лишние темы.

Вкратце: не используйте асинхронность на стороне сервера, если у вас нет работы, связанной с вводом-выводом, для выполнения на стороне сервера - если вы ограничены процессором, придерживайтесь синхронной реализации сервера (возможно, в сочетании с MaxConcurrentCalls , равное числу ядер ЦП на сервере).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...