C# .NET Web 服务和 BackgroundWorker 线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/228775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:03:22  来源:igfitidea点击:

.NET Web Service & BackgroundWorker threads

c#asp.netmultithreadingbackgroundworker

提问by Pure.Krome

I'm trying to do some async stuff in a webservice method. Let say I have the following API call: http://www.example.com/api.asmx

我正在尝试在 webservice 方法中做一些异步的东西。假设我有以下 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 web 应用程序中进行后台或分叉线程的错误方式吗?

采纳答案by Marc Gravell

BackgroundWorkeris useful when you need to synchronize back to (for example) a UI* thread, eg for affinity reasons. In this case, it would seem that simply using ThreadPoolwould be more than adequate (and much simpler). If you have high volumes, then a producer/consumer queue may allow better throttling (so you don't drown in threads) - but I suspect ThreadPoolwill be fine here...

BackgroundWorker当您需要同步回(例如)UI* 线程时(例如出于亲和力原因)非常有用。在这种情况下,似乎简单地使用ThreadPool就足够了(而且简单得多)。如果您的容量很大,那么生产者/消费者队列可能会允许更好的节流(这样您就不会淹没在线程中)-但我怀疑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). Care to elaborate? It lookslike you are pausing your actual web page (i.e. the Sleep happens on the web-page thread, not the e-mail thread). What are you trying to do here?

另外 - 我不太确定你想通过睡觉来达到什么目的?这只会占用一个线程(不使用 CPU,但也无济于事)。想详细说明?它看起来像你暂停您的实际网页(即睡眠发生在Web页主题,而不是邮件线程)。你想在这里做什么?

*=actually, it will use whatever sync-context is in place

*=实际上,它将使用任何适当的同步上下文

回答by huseyint

It may torn down because after 20 seconds, that BackgroundWorker instance may be garbage collected because it has no references (gone out of scope).

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

回答by Marc Gravell

Re producer/consumer; basically - it is just worth keeping somekind of throttle. At the simplest level, a Semaphorecould be used (along with the regular ThreadPool) to limit things to a known amount of work (to avoid saturating the thread pool); but a producer/consumer queue would probably be more efficient and managed.

再生产者/消费者;基本上 - 保持某种油门是值得的。在最简单的层面上,Semaphore可以使用 a (与常规 一起ThreadPool)将事情限制在已知的工作量(以避免线程池饱和);但生产者/消费者队列可能会更有效率和管理。

Jon Skeet has such a queue here(CustomThreadPool). I could probably write some notes about it if you wanted.

乔恩斯基特有这样的队列在这里CustomThreadPool)。如果你愿意,我可能会写一些关于它的笔记。

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; 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.

这就是说:如果您调用外部网站,很可能您会在网络 IO/完成端口上等待很多时间;因此,您可以拥有稍多的线程数……显然(相比之下)如果工作受 CPU 限制,那么线程数多于 CPU 内核数毫无意义。