Frage

Ich versuche, einige async Sachen in einer Webservice-Methode zu tun. Lassen Sie sagen, ich die folgende API-Aufruf haben: http://www.example.com/api.asmx

und die Methode wird aufgerufen, GetProducts () .

ich diese GetProducts Methoden, ich ein paar Sachen zu tun (z. B. bekommen Daten aus der Datenbank), dann, kurz bevor ich das Ergebnis zurück, ich will etwas async Dinge tun (zB. Bitte senden Sie mir eine E-Mail).

Also das ist, was ich getan habe.

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

Nun, wenn ich diesen Code ausführen wird die E-Mail nie gesendet. Wenn ich die Thread.Sleep Kommentar- aus .. dann wird die E-Mail gesendet wird.

So ... warum ist es, dass der Hintergrund-Worker-Thread wird abgerissen? ist es für den übergeordneten Thread abhängig? Ist dies der falsche Weg soll ich Hintergrund oder gegabelt Threading tun, in asp.net Web-Anwendungen?

War es hilfreich?

Lösung

BackgroundWorker ist nützlich, wenn Sie zurück zu (zum Beispiel) ein UI * Thread, zB für die Affinität Gründe synchronisieren müssen. In diesem Fall würde es scheinen, dass einfach ThreadPool verwenden würde mehr als ausreichend sein (und viel einfacher). Wenn Sie hohe Volumina aufweisen, dann kann ein Erzeuger / Verbraucher-Warteschlange besser Drosselung erlauben (so dass Sie nicht ertrinken in Threads) - aber ich vermute, ThreadPool wird gut hier ...

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

Auch - ich bin mir nicht ganz sicher, was Sie schlafen erreichen? Dies wird nur einen Thread binden (nicht mit CPU, aber auch nicht gut tun). Pflege zu erarbeiten? Es sieht , wie Sie Ihre eigentliche Webseite pausieren (das heißt der Schlaf auf der Web-Seite Thread geschieht, nicht die E-Mail-Thread). Was versuchen Sie, hier zu tun?

* = tatsächlich, wird es verwenden, was Sync-Kontext vorhanden ist

Andere Tipps

Re Erzeuger / Verbraucher; im Grunde genommen - es ist nur wert zu halten einig Art von Gas. Auf der einfachstenen Ebene könnte ein Semaphore (zusammen mit dem regulären ThreadPool) verwendet werden, was zu einer bekannten Menge an Arbeit zu begrenzen (zu vermeiden, dass der Thread-Pool zu sättigen); aber ein Erzeuger / Verbraucher-Warteschlange wäre wahrscheinlich effiziente und verwaltet werden.

Jon Skeet hat eine solche Warteschlange hier (CustomThreadPool). Ich könnte wahrscheinlich ein paar Notizen darüber schreiben, wenn man will.

Das heißt: Wenn Sie auf eine externe Web-Site abzublasen, es sehr wahrscheinlich ist, dass Sie eine Menge wartet auf Netzwerk-IO / Abschluss-Ports haben wird; als solche können Sie eine etwas höhere Anzahl von Threads haben ... offensichtlich (im Gegensatz), wenn die Arbeit war CPU-gebunden ist, gibt es keinen Punkt mehr Fäden, als Sie CPU-Kerne haben.

Es kann da nach 20 Sekunden abgerissen, dass Background Beispiel kann Müll gesammelt werden, weil es keine Referenzen hat (out of scope gegangen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top