TsgcWebSocketClient › Olaylar › OnQueueDrained
Giden ileti kuyruğu, ileti tutar durumdan boş duruma geçtiğinde tetiklenir.
property OnQueueDrained: TsgcWSQueueDrainedEvent;
// TsgcWSQueueDrainedEvent = procedure(Connection: TsgcWSConnection) of object
—
Yalnızca ileti kuyruklama etkinken tetiklenir, yani QueueOptions.Text.Level, QueueOptions.Binary.Level veya QueueOptions.Ping.Level qmNone dışında bir değere ayarlandığında. Kuyruk yoksa boşaltılacak bir şey de yoktur ve varsayılan qdmTransition modunda olay hiçbir zaman tetiklenmez.
İşleyici, bağlantı iş parçacığı üzerinde satır içi olarak çalışır ve bu bileşenin diğer tüm olaylarının aksine kasıtlı olarak NotifyEvents üzerinden aktarılmaz; bu nedenle kullanıcı arayüzüne dokunmamalıdır. Bu sapma bilinçlidir. Olayın tüm değeri, bağlantı döngüsünün tam o noktasında, kuyruk boşaldıktan hemen sonra ve bir sonraki okumadan önce, soket hâlâ boştayken çalışmasıdır; böylece uygulama beklemeden bir sonraki parçayı serbest bırakabilir. Olayı ana iş parçacığına aktarmak bunu ortadan kaldırırdı. Herhangi bir form, ızgara veya etiket güncellemesinin uygulamanın kendisi tarafından TThread.Queue, TThread.Synchronize veya ana iş parçacığına gönderilen bir mesajla aktarılması gerekir.
İşleyicinin içinde oluşan istisnalar yakalanır ve yok sayılır; böylece boşaltma her zaman tamamlanır. Başarısız olan bir işleyici bunu sessizce yapar, bu yüzden bir hatanın raporlanması gerekiyorsa gövdeyi kendi try..except bloğuna sarın.
QueueOptions.DrainedMode özelliği, olayın ne zaman tetikleneceğini seçer. qdmTransition (varsayılan) ile olay, aşağıda açıklandığı gibi, dolu durumdan boş duruma her geçişte bir kez tetiklenir. qdmEveryPass ile olay, kuyruklar gönderildikten hemen sonra, kuyruk zaten boş olsa bile ve Text.Level, Binary.Level ve Ping.Level üçü de qmNone olsa bile, bağlantı döngüsünün her geçişinde (yaklaşık her Options.ReadTimeout milisaniyede bir) tetiklenir; bu nedenle sahte bir kuyruk düzeyine gerek yoktur. Bu modda işleyici, bağlantı iş parçacığında bağlantı başına bir kancadır, örneğin bir bağlantıya yapılan her yazmanın kendi iş parçacığından gerçekleşmesi için bekleyen uygulama verilerini WriteData ile göndermek üzere (Binary.Level qmNone iken, olayın içindeki WriteData doğrudan sokete yazar). Geçiş moduna benzer şekilde satır içi çalışır ve NotifyEvents'i izlemez, bu nedenle işleyici hızlı olmalı ve kullanıcı arayüzüne dokunmamalıdır. Her bağlantı, bağlanırken kuyruk seçeneklerini kopyalar, bu nedenle DrainedMode değerini bileşeni etkinleştirmeden önce ayarlayın, zaten açık olan bağlantılar önceki modu korur.
qdmTransition modunda olay, bağlantı döngüsünün her geçişinde değil, dolu durumdan boş duruma her geçişte bir kez tetiklenir. Bir yoğun gönderimin bittiğine dair bir sinyal değildir. Boşaltma yavaş bir üreticiye ayak uyduruyorsa, her bir ileti kendi olayını tetikleyebilir, çünkü her ileti bir sonraki kuyruğa alınmadan önce yazılıp gönderilir. Olayın bildirdiği tek şey, bu bağlantının kuyruğunun şu anda boş olduğudur, fazlası değil.
Tipik kullanımı akış denetimidir. İstemci toplu veri akışı yaparken, üreticinin belleği doldurmak yerine soketin hızını izlemesi için bir sonraki parçayı serbest bırakmak üzere bu olayı kullanın. Dur ve bekle alışverişi yerine bir kredi penceresi işletmek için, bağlantı için hâlâ kaç iletinin kuyrukta olduğunu bildiren TsgcWSConnection sınıfının PendingCount özelliğiyle birlikte kullanın.
Yönetilen .NET sürümü aynı olayı aynı anlamla tetikler. Tek fark, olayın ne sıklıkta geldiğidir. Delphi boşaltması bağlantı döngüsünün her geçişinde bir kez çalışır; bu geçişler Options.ReadTimeOut milisaniye aralıklıdır ve varsayılan değer 10'dur, bu nedenle yavaş bir ileti akışı az sayıda olayda birleştirilir. Yönetilen boşaltma olay tabanlıdır ve aynı akış daha fazla olay tetikleyebilir. Yoğun gönderimler her ikisinde de aynı şekilde davranır.
procedure OnQueueDrained(Connection: TsgcWSConnection);
begin
// runs on the connection thread, do not touch the user interface here
Connection.WriteData(GetNextChunk);
end;
// qdmEveryPass: runs on every pass of the connection loop
oClient.QueueOptions.DrainedMode := qdmEveryPass;
oClient.QueueOptions.Ping.Level := qmLevel1;
procedure OnQueueDrained(Connection: TsgcWSConnection);
begin
// runs on the connection thread, do not touch the user interface here
if Connection.Disconnected then
exit;
if HasPendingData then
Connection.WriteData(GetPendingData);
end;