2016-07-26 2 views
0

Допустим, у меня есть следующий ApiController в моем ASP.NET WebAPI Применение:WebAPI контроллер повторного

class MyApiController : ApiController 
{ 
    private string str; 

    [HttpGet] 
    public string SetStr(string str) 
    { 
     this.str = str; 
     MaybeSleep(); // Some executions take longer, some don't. 
     return this.str; 
    } 
} 

(Реальность немного сложнее, но это должно быть все, что имеет значение)

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

В двух средах, однако, str иногда «волшебные» изменения между множеством и возвратом, даже без слишком большой нагрузки на сервер. Тем не менее, он всегда изменяется на значения, которые были отправлены на сервер примерно в это время, а не только те, которые были отправлены в этом запросе.

Итак, мои вопросы:

  • ли ApiController повторное поведение, которое я должен только ожидать, или должен быть создан новый ApiController, используется и уничтожили для каждого отдельного запроса на процессы сервера?
  • Это поведение зависит от версии ASP.NET, версии IIS и/или настройки Web.config?
  • Есть ли документация о поведении частных переменных ApiController, доступных от Microsoft?
  • Или это, возможно, известная ошибка в определенной версии .NET или ASP.NET?
+2

Новый контроллер создается для каждого запроса так что если у вас есть общий ресурс вмешательства, это должно быть изолировано. –

+1

Я уверен, что ваш пример неверен и не отражает ситуацию в реальном мире. Прежде всего, я не думаю, что контроллеры могут быть повторно использованы таким образом (если бы они могли быть действительно обеспокоены некоторыми из моих проектов). Второе повторное использование или нет, вы просто возвращаете аргумент. Вы используете это поле как своего рода локальную переменную. – Stilgar

+0

Если вы не используете одну и ту же ссылку ApiController для нескольких вызовов. (Как создание глобального контроллера и вызов метода, который будет переписывать атрибут для каждого вызова), вам должно быть хорошо идти. И, как сказал Стилгар, это, вероятно, не вся ситуация, и, вероятно, это больше, чем кажется. –

ответ

1

Запрос не должен изменять состояние контроллера. От метода ввода до любых других вызванных методов вы можете передавать параметры по мере необходимости, поэтому нет необходимости изменять сам объект контроллера в соответствии с запросом.

Если есть какое-то состояние, которое необходимо поддерживать на протяжении всего запроса, что вы не можете передавать параметры другим методам, лучшее место для этого можно найти на HttpContext, поскольку это всегда относится к запросу. (Даже тогда этот сценарий, вероятно, не слишком распространен.)

Вместо этого:

public string SetStr(string str) 
{ 
    this.str = str; 
    MaybeSleep(); // Some executions take longer, some don't. 
    return this.str; 
} 

это:

public string SetStr(string str) 
{ 
    HttpContext.Items["str"] = str; //I'd declare a constant for "str" 
    MaybeSleep(); 
    return HttpContext.Items["str"]; 
} 
+0

У вас есть ссылка на резервное копирование вашего первого предложения? Кажется, это противоречит другому ответу, а также трем комментариям. – Alexander

+0

Нет, не знаю. Я также не согласен с другими комментариями - мой ответ дополняет друг друга. Не существует правила, согласно которому контроллер не может взять какое-либо состояние из запроса, но он идет против зерна. Если ваши контроллеры не имеют гражданства, вам не придется беспокоиться о том, будут ли они повторно использоваться. –

1

ли ApiController повторного поведения, которое я просто ожидать, или должен быть создан новый ApiController, используется и уничтожается при каждом одного запроса серверных процессов?

Когда запрос получен, новый экземпляр контроллера создается ControllerFactory или DependencyResolver.

В основном основной поток создает экземпляр контроллера, а затем один и тот же экземпляр разделяется между несколькими потоками, пока запрос не будет завершен.

Остальная часть вопроса больше не актуальна, поскольку первое предположение неверно.

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

Вы можете прочитать в блоге Скотта Хансельман в - How to run Background Tasks in ASP.NET

Смежные вопросы