Проблема с потоками ASP.NET

Проблема: я работаю над приложением ASP.NET 2.0/C#, и мне нужно сделать следующее:

У меня есть функция, которую я использую из сторонней библиотеки, скажем

MyFunctions.CalculateTotal(int a, int b);

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

MyFunctions.ThreadExit();

Проблема в том, что это приведет к выходу из текущего потока, и после этого я не смогу использовать какие-либо другие функции. Кроме того, мне не кажется целесообразным убивать такой поток asp.net.

Я подумал о том, чтобы создать отдельный поток, но это был бы взлом.

Global.asax имеет такие события для всего приложения, как Application_Start/End.

Я знаю, что нет такого события, как Application_ThreadStart/End, но, может быть, что-то в этом роде?

Любое другое предложение для возможного решения?


person makstaks    schedule 12.01.2010    source источник
comment
Итак, вы говорите, что если я вызову CalculateTotal из потока A, он не будет продолжаться после этого вызова, и вам придется вызывать ThreadExit из другого потока?   -  person AaronLS    schedule 12.01.2010
comment
Эта сторонняя библиотека отстой...^^   -  person Daniel Brückner    schedule 12.01.2010
comment
aronis - нет, поток A продолжится, поэтому, возможно, мне следует отредактировать свой пост, чтобы сказать, что он внутренне блокирует ресурс, а threadexit все очищает.   -  person makstaks    schedule 12.01.2010


Ответы (3)


(обновлено)

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

int result;
var thread = new Thread(_ => {
  result = MyFunctions.CalculateTotal(a, b);
  MyFunctions.ThreadExit();
}).Start();
person G-Wiz    schedule 12.01.2010
comment
извините, я исправил свой пост, чтобы сказать вместо этого. Известная проблема заключается в том, что поток блокирует ресурсы. Итак, есть еще одна функция, которую нужно вызвать после, чтобы все очистить. - person makstaks; 12.01.2010
comment
Ах хорошо. Я думаю, что я бы все еще пошел с этим подходом. Вы в основном делаете вызов в эту стороннюю библиотеку в своем собственном потоке. Таким образом, у вас есть собственный контекст выполнения/потока, который он может очистить в конце. - person G-Wiz; 12.01.2010
comment
знаете ли вы что-нибудь в asp.net, чем я мог бы воспользоваться, чтобы мне не приходилось каждый раз настраивать это? - person makstaks; 12.01.2010
comment
Вы можете создать класс-оболочку для библиотеки. Самым простым подходом был бы статический класс, который просто предоставляет каждый из методов в MyFunctions в прокси-методе, который реализует приведенный выше шаблон. Однако имейте в виду, что управление потоками стоит дорого, и это может быть не идеально в вашем конкретном сценарии использования. Если вы вызываете его 50 раз в секунду, вы можете рассмотреть (гораздо более продвинутый) шаблон производитель/потребитель для управления потоками. OTOH, если ваша нагрузка скачкообразна и непостоянна, возможно, стоит рассмотреть приведенный выше шаблон или ThreadPool. - person G-Wiz; 13.01.2010
comment
@wingho: я думаю, что это может быть единственная библиотека, настолько сильно сломанная, что для нее нужен отдельный метод очистки. Было бы удивительно, если бы в ASP.NET было исправление для этого. - person John Saunders; 13.01.2010

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

Кстати, эта сторонняя библиотека звучит просто ужасно! ;-)

person Adam Ralph    schedule 12.01.2010

Эта статья может вам помочь, поскольку в ней используется IHttpAsyncHandler — тогда вы должны использовать это как «asynchandler.ashx». Это требует от вас знания об HttpHandlers, если вы не т уже хотя, так что это не мгновенное решение.

Немного измененная версия их кода с вашими MyFunctions:

public class AsyncHandler : IHttpAsyncHandler
{ 
  public void ProcessRequest(HttpContext ctx)
  {
    // not used
  }

  public bool IsReusable
  {
    get { return false;}
  }

  public IAsyncResult BeginProcessRequest(HttpContext ctx, 
                                          AsyncCallback cb, 
                                          object obj)
  {
    AsyncRequestState reqState = 
                      new AsyncRequestState(ctx, cb, obj);
    AsyncRequest ar = new AsyncRequest(reqState);
    ThreadStart ts = new ThreadStart(ar.ProcessRequest);
    Thread t = new Thread(ts);
    t.Start();

    return reqState;
  }

  public void EndProcessRequest(IAsyncResult ar)
  {
    AsyncRequestState ars = ar as AsyncRequestState;
    if (ars != null)
    {
     // here you could perform some cleanup, write something else to the
     // Response, or whatever else you need to do
    }
  }
}

public class AsyncRequest
{
  private AsyncRequestState _asyncRequestState;

  public AsyncRequest(AsyncRequestState ars)
  {
    _asyncRequestState = ars;
  }

  public void ProcessRequest()
  {
    MyFunctions.CalculateTotal(int a, int b);

    // tell asp.net I am finished processing this request
    _asyncRequestState.CompleteRequest();
  }
}

Измените их имена переменных, они противны.

person Chris S    schedule 13.01.2010