2008-10-23 3 views
14

Я пытаюсь выполнить некоторые асинхронные действия в методе webservice. Скажем, у меня есть следующий вызов API: http://www.example.com/api.asmx.NET Web Service & BackgroundWorker threads

и метод называется GetProducts().

Это методы GetProducts, я делаю некоторые вещи (например, получаю данные из базы данных), а затем перед тем, как я верну результат, я хочу сделать некоторые асинхронные вещи (например, отправьте мне электронное письмо).

Так вот что я сделал.

[WebMethod(Description = "Bal blah blah.")] 
public IList<Product> GetProducts() 
{ 
    // Blah blah blah .. 
    // Get data from DB .. hi DB! 
    // var myData = ....... 
    // Moar clbuttic blahs :) (yes, google for clbuttic if you don't know what that is) 

    // Ok .. now send me an email for no particular reason, but to prove that async stuff works. 
    var myObject = new MyObject(); 
    myObject.SendDataAsync(); 

    // Ok, now return the result. 
    return myData; 
    } 
} 

public class TrackingCode 
{ 
    public void SendDataAsync() 
    { 
     var backgroundWorker = new BackgroundWorker(); 
     backgroundWorker.DoWork += BackgroundWorker_DoWork; 
     backgroundWorker.RunWorkerAsync(); 
     //System.Threading.Thread.Sleep(1000 * 20); 
    } 

    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     SendEmail(); 
    } 
} 

Теперь, когда я запускаю этот код, письмо никогда не отправляется. Если я раскомментирую Thread.Sleep, тогда отправляется электронное письмо.

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

ответ

17

BackgroundWorker полезен, если вам необходимо синхронизировать обратную связь (например) с потоком пользовательского интерфейса, например, по причинам близости. В этом случае казалось бы, что просто использование ThreadPool было бы более чем достаточно (и намного проще). Если у вас есть большие объемы, то очереди производитель/потребитель может позволить лучше дросселирования (так что вы не утонуть в потоках), - но я подозреваю, что ThreadPool будет хорошо здесь ...

public void SendDataAsync() 
{ 
    ThreadPool.QueueUserWorkItem(delegate 
    { 
     SendEmail(); 
    }); 
} 

Кроме того - я не совсем уверен, чего вы хотите достичь, спать? Это будет просто связать поток (не используя CPU, но ничего хорошего не делать). Поразмыслить? Это выглядит, как будто вы приостановили свою фактическую веб-страницу (т. Е. Сон происходит в теме веб-страницы, а не в электронной почте). Что вы здесь делаете?

* = на самом деле, он будет использовать любую синхронизацию контекста на месте

+0

Сон закомментирован. Я поставил это, чтобы посмотреть, могу ли я отправить электронное письмо. когда сон НЕОБХОДИЛ, то выполняется код потока рабочего фона. когда код по достоинству оценен, тогда код рабочего рабочего рабочего фона никогда не выполняется. Вместо этого попробую использовать ThreadPool. – 2008-10-23 23:14:05

+0

> * Если у вас большие тома, тогда очередь производителей/потребителей может позволить лучше дросселировать (чтобы вы не тонули в потоках) * ooooooo !!!Я рад, что действительно поднял этот момент! метод веб-службы на самом деле большой объем! Кроме того, чтобы сделать действительно интересным, на самом деле он не отправляет электронное письмо, но на самом деле попадает на другой внешний веб-сайт (ekk, не спрашивайте) ... так что вы бы предложили мне сделать эту очередь производителей/потребителей? Если так ... это хорошая страница для ссылки? http://www.albahari.com/threading/part4.aspx (пожалуйста, прокрутите вниз по справедливому биту в код + пример). мысли? – 2008-10-23 23:33:01

0

может снес, потому что после 20 секунд, что экземпляр BackgroundWorker может быть мусор, потому что у него нет ссылок (ушли из сферы).

1

Re производитель/потребитель; в основном - стоит оставить вид дроссельной заслонки. На простейшем уровне можно использовать Semaphore (наряду с обычным ThreadPool), чтобы ограничить работу известным количеством работы (чтобы избежать насыщения пула потоков); но очередь производителей/потребителей, вероятно, будет более эффективной и управляемой.

У Jon Skeet есть такая очередь here (CustomThreadPool). Возможно, я мог бы написать некоторые заметки об этом, если бы захотел.

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