简体   繁体   English

.NET Web服务和BackgroundWorker线程

[英].NET Web Service & BackgroundWorker threads

I'm trying to do some async stuff in a webservice method. 我试图在webservice方法中做一些异步的东西。 Let say I have the following API call: http://www.example.com/api.asmx 假设我有以下API调用: http//www.example.com/api.asmx

and the method is called GetProducts() . 并且该方法称为GetProducts()

I this GetProducts methods, I do some stuff (eg. get data from database) then just before i return the result, I want to do some async stuff (eg. send me an email). 我这个GetProducts方法,我做了一些事情(例如从数据库中获取数据)然后在我返回结果之前,我想做一些异步的东西(例如给我发电子邮件)。

So this is what I did. 所以这就是我所做的。

[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();
    }
}

Now, when I run this code the email is never sent. 现在,当我运行此代码时,电子邮件永远不会发送。 If I uncomment out the Thread.Sleep .. then the email is sent. 如果我取消注释Thread.Sleep ..然后发送电子邮件。

So ... why is it that the background worker thread is torn down? 那么......为什么背景工作者线程被拆除了? is it dependant on the parent thread? 它依赖于父线程吗? Is this the wrong way I should be doing background or forked threading, in asp.net web apps? 这是我在asp.net网络应用程序中做背景或分叉线程的错误方法吗?

BackgroundWorker is useful when you need to synchronize back to (for example) a UI* thread, eg for affinity reasons. 当您需要同步回(例如)UI *线程时, BackgroundWorker非常有用,例如出于亲和力原因。 In this case, it would seem that simply using ThreadPool would be more than adequate (and much simpler). 在这种情况下,似乎只使用ThreadPool就足够了(而且更简单)。 If you have high volumes, then a producer/consumer queue may allow better throttling (so you don't drown in threads) - but I suspect ThreadPool will be fine here... 如果你有大量的,那么生产者/消费者队列可能允许更好的限制(所以你不要淹没在线程中) - 但我怀疑ThreadPool在这里会好的......

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

Also - I'm not quite sure what you want to achieve by sleeping? 另外 - 我不太确定你想通过睡觉达到什么目的? This will just tie up a thread (not using CPU, but doing no good either). 这只会占用一个线程(不使用CPU,但也没有好处)。 Care to elaborate? 注意详细说明? It looks like you are pausing your actual web page (ie the Sleep happens on the web-page thread, not the e-mail thread). 看起来你正在暂停你的实际网页(即睡眠发生在网页线程,而不是电子邮件线程)。 What are you trying to do here? 你想在这做什么?

*=actually, it will use whatever sync-context is in place * =实际上,它将使用任何同步上下文

Re producer/consumer; 再生产者/消费者; basically - it is just worth keeping some kind of throttle. 基本上 - 这是值得保持某种油门。 At the simplest level, a Semaphore could be used (along with the regular ThreadPool ) to limit things to a known amount of work (to avoid saturating the thread pool); 在最简单的级别,可以使用Semaphore (以及常规的ThreadPool )将事物限制为已知的工作量(以避免使线程池饱和); but a producer/consumer queue would probably be more efficient and managed. 但生产者/消费者队列可能会更有效率和管理。

Jon Skeet has such a queue here ( CustomThreadPool ). Jon Skeet 在这里有一个这样的队列( CustomThreadPool )。 I could probably write some notes about it if you wanted. 如果你愿意,我可能会写一些关于它的笔记。

That said: if you are calling off to an external web-site, it is quite likely that you will have a lot of waits on network IO / completion ports; 这就是说:如果你正在呼叫一个外部网站,你很可能会在网络IO /完成端口上有很多等待; as such, you can have a slightly higher number of threads... obviously (by contrast) if the work was CPU-bound, there is no point having more threads than you have CPU cores. 因此,你可以拥有稍高的线程数......显然(相比之下)如果工作受CPU约束,那么没有任何一点比你有CPU核心更多的线程。

它可能会被拆除,因为在20秒之后,BackgroundWorker实例可能会被垃圾收集,因为它没有引用(超出范围)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM