Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu belgede, uygulamanızda veri akışını kullanırken belirli bir görev zamanlayıcısını nasıl ilişkilendirdiğiniz gösterilmektedir. Örnek, bir Windows Forms uygulamasında System.Threading.Tasks.ConcurrentExclusiveSchedulerPair sınıfını kullanarak okuyucu görevlerinin ne zaman etkin olduğunu ve bir yazar görevinin aktif olduğunu gösterir. Ayrıca bir veri akışı bloğunun TaskScheduler.FromCurrentSynchronizationContext kullanıcı arabirimi iş parçacığında çalışmasını sağlamak için yöntemini kullanır.
Not
TPL veri akışı kitaplığı ( System.Threading.Tasks.Dataflow ad alanı), .NET 6 ve sonraki sürümlerde bulunur. .NET Framework ve .NET Standard projeleri için System.Threading.Tasks.Dataflow NuGet paketini yüklemeniz📦 gerekir.
Windows Forms Uygulaması Oluşturmak için
Visual C# veya Visual Basic Windows Forms Uygulaması projesi oluşturun. Aşağıdaki adımlarda projenin adı
WriterReadersWinFormsverilmiştir.Ana formun form tasarımcısında Form1.cs (Visual Basic için Form1.vb), dört CheckBox denetim ekleyin. Özelliği Text için olarak ayarlayın,
checkBox1için Okuyucu 2 olarak ayarlayın,checkBox2için Okuyucu 3 olarak ayarlayın, vecheckBox3için Yazıcı olarak ayarlayın. Her denetimin Enabled özelliğiniFalseolarak ayarlayın.Forma bir Timer denetim ekleyin. Interval özelliğini
2500olarak ayarlayın.
Veri Akışı İşlevselliği Ekleme
Bu bölümde, uygulamaya katılan veri akışı bloklarının nasıl oluşturulacağı ve her birinin bir görev zamanlayıcıyla nasıl ilişkilendirılacağı açıklanır.
Uygulamaya Veri Akışı İşlevselliği Eklemek için
Projenizde System.Threading.Tasks.Dataflow.dll'e bir başvuru ekleyin.
Form1.cs (Visual Basic için Form1.vb) aşağıdaki
usingyönergeleri (ImportsVisual Basic'te) içerdiğinden emin olun.using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; using System.Windows.Forms;Imports System.Threading Imports System.Threading.Tasks Imports System.Threading.Tasks.DataflowSınıfına BroadcastBlock<T> bir
Form1veri üyesi ekleyin.// Broadcasts values to an ActionBlock<int> object that is associated // with each check box. BroadcastBlock<int> broadcaster = new BroadcastBlock<int>(null);' Broadcasts values to an ActionBlock<int> object that is associated ' with each check box. Private broadcaster As New BroadcastBlock(Of Integer)(Nothing)Oluşturucuda
Form1, çağrısındanInitializeComponentsonra nesnelerin durumunu ActionBlock<TInput> değiştiren bir CheckBox nesne oluşturun.// Create an ActionBlock<CheckBox> object that toggles the state // of CheckBox objects. // Specifying the current synchronization context enables the // action to run on the user-interface thread. var toggleCheckBox = new ActionBlock<CheckBox>(checkBox => { checkBox.Checked = !checkBox.Checked; }, new ExecutionDataflowBlockOptions { TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext() });' Create an ActionBlock<CheckBox> object that toggles the state ' of CheckBox objects. ' Specifying the current synchronization context enables the ' action to run on the user-interface thread. Dim toggleCheckBox = New ActionBlock(Of CheckBox)(Sub(checkBox) checkBox.Checked = Not checkBox.Checked, New ExecutionDataflowBlockOptions With {.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()})Oluşturucuda
Form1bir nesne ve her ConcurrentExclusiveSchedulerPair nesne için bir ActionBlock<TInput>ActionBlock<TInput> nesne olmak üzere dört CheckBox nesne oluşturun. Her ActionBlock<TInput> nesne için, ExecutionDataflowBlockOptions özelliği okuyucular için TaskScheduler özelliğiyle, yazan için ise ConcurrentScheduler özelliğiyle ayarlanmış bir ExclusiveScheduler nesneyi belirtin.// Create a ConcurrentExclusiveSchedulerPair object. // Readers will run on the concurrent part of the scheduler pair. // The writer will run on the exclusive part of the scheduler pair. var taskSchedulerPair = new ConcurrentExclusiveSchedulerPair(); // Create an ActionBlock<int> object for each reader CheckBox object. // Each ActionBlock<int> object represents an action that can read // from a resource in parallel to other readers. // Specifying the concurrent part of the scheduler pair enables the // reader to run in parallel to other actions that are managed by // that scheduler. var readerActions = from checkBox in new CheckBox[] {checkBox1, checkBox2, checkBox3} select new ActionBlock<int>(milliseconds => { // Toggle the check box to the checked state. toggleCheckBox.Post(checkBox); // Perform the read action. For demonstration, suspend the current // thread to simulate a lengthy read operation. Thread.Sleep(milliseconds); // Toggle the check box to the unchecked state. toggleCheckBox.Post(checkBox); }, new ExecutionDataflowBlockOptions { TaskScheduler = taskSchedulerPair.ConcurrentScheduler }); // Create an ActionBlock<int> object for the writer CheckBox object. // This ActionBlock<int> object represents an action that writes to // a resource, but cannot run in parallel to readers. // Specifying the exclusive part of the scheduler pair enables the // writer to run in exclusively with respect to other actions that are // managed by the scheduler pair. var writerAction = new ActionBlock<int>(milliseconds => { // Toggle the check box to the checked state. toggleCheckBox.Post(checkBox4); // Perform the write action. For demonstration, suspend the current // thread to simulate a lengthy write operation. Thread.Sleep(milliseconds); // Toggle the check box to the unchecked state. toggleCheckBox.Post(checkBox4); }, new ExecutionDataflowBlockOptions { TaskScheduler = taskSchedulerPair.ExclusiveScheduler }); // Link the broadcaster to each reader and writer block. // The BroadcastBlock<T> class propagates values that it // receives to all connected targets. foreach (var readerAction in readerActions) { broadcaster.LinkTo(readerAction); } broadcaster.LinkTo(writerAction);' Create a ConcurrentExclusiveSchedulerPair object. ' Readers will run on the concurrent part of the scheduler pair. ' The writer will run on the exclusive part of the scheduler pair. Dim taskSchedulerPair = New ConcurrentExclusiveSchedulerPair() ' Create an ActionBlock<int> object for each reader CheckBox object. ' Each ActionBlock<int> object represents an action that can read ' from a resource in parallel to other readers. ' Specifying the concurrent part of the scheduler pair enables the ' reader to run in parallel to other actions that are managed by ' that scheduler. Dim readerActions = From checkBox In New CheckBox() {checkBox1, checkBox2, checkBox3} _ Select New ActionBlock(Of Integer)(Sub(milliseconds) ' Toggle the check box to the checked state. ' Perform the read action. For demonstration, suspend the current ' thread to simulate a lengthy read operation. ' Toggle the check box to the unchecked state. toggleCheckBox.Post(checkBox) Thread.Sleep(milliseconds) toggleCheckBox.Post(checkBox) End Sub, New ExecutionDataflowBlockOptions With {.TaskScheduler = taskSchedulerPair.ConcurrentScheduler}) ' Create an ActionBlock<int> object for the writer CheckBox object. ' This ActionBlock<int> object represents an action that writes to ' a resource, but cannot run in parallel to readers. ' Specifying the exclusive part of the scheduler pair enables the ' writer to run in exclusively with respect to other actions that are ' managed by the scheduler pair. Dim writerAction = New ActionBlock(Of Integer)(Sub(milliseconds) ' Toggle the check box to the checked state. ' Perform the write action. For demonstration, suspend the current ' thread to simulate a lengthy write operation. ' Toggle the check box to the unchecked state. toggleCheckBox.Post(checkBox4) Thread.Sleep(milliseconds) toggleCheckBox.Post(checkBox4) End Sub, New ExecutionDataflowBlockOptions With {.TaskScheduler = taskSchedulerPair.ExclusiveScheduler}) ' Link the broadcaster to each reader and writer block. ' The BroadcastBlock<T> class propagates values that it ' receives to all connected targets. For Each readerAction In readerActions broadcaster.LinkTo(readerAction) Next readerAction broadcaster.LinkTo(writerAction)Form1oluşturucusunda, Timer nesnesini başlatın.// Start the timer. timer1.Start();' Start the timer. timer1.Start()Ana form tasarımcısında, zamanlayıcı olayı için Tick bir olay işleyici oluşturun.
Zamanlayıcı için Tick etkinliğini uygulayın.
// Event handler for the timer. private void timer1_Tick(object sender, EventArgs e) { // Post a value to the broadcaster. The broadcaster // sends this message to each target. broadcaster.Post(1000); }' Event handler for the timer. Private Sub timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles timer1.Tick ' Post a value to the broadcaster. The broadcaster ' sends this message to each target. broadcaster.Post(1000) End Sub
toggleCheckBox Veri akışı bloğu kullanıcı arabirimi üzerinde hareket ettiğinden, bu eylemin kullanıcı arabirimi iş parçacığında gerçekleşmesi önemlidir. Bunu başarmak için, oluşturma sırasında özelliği ExecutionDataflowBlockOptions olarak ayarlanmış bir TaskScheduler nesne sağlayan bir TaskScheduler.FromCurrentSynchronizationContext nesne sağlar.
FromCurrentSynchronizationContext yöntemi, geçerli eşitleme bağlamında çalışma gerçekleştiren bir TaskScheduler nesnesi oluşturur.
Form1 Oluşturucu kullanıcı arabirimi iş parçacığından çağrıldığından, veri akışı bloğu eylemi toggleCheckBox kullanıcı arabirimi iş parçacığında da çalışır.
Bu örnek ayrıca bazı veri akışı bloklarının ConcurrentExclusiveSchedulerPair eşzamanlı olarak davranmasını sağlamak için sınıfını ve aynı ConcurrentExclusiveSchedulerPair nesne üzerinde çalışan diğer tüm veri akışı bloklarına göre özel işlem yapmak üzere başka bir veri akışı bloğunu kullanır. Bu teknik, birden çok veri akışı bloğu bir kaynağı paylaştığında ve bazıları bu kaynağa özel erişim gerektirdiğinde kullanışlıdır, çünkü bu kaynağa erişimi el ile eşitleme gereksinimi ortadan kalkar. El ile eşitlemenin ortadan kaldırılması kodu daha verimli hale getirir.
Örnek
Aşağıdaki örnek, Form1.cs (Visual Basic için Form1.vb) kodunun tamamını gösterir.
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
namespace WriterReadersWinForms
{
public partial class Form1 : Form
{
// Broadcasts values to an ActionBlock<int> object that is associated
// with each check box.
BroadcastBlock<int> broadcaster = new BroadcastBlock<int>(null);
public Form1()
{
InitializeComponent();
// Create an ActionBlock<CheckBox> object that toggles the state
// of CheckBox objects.
// Specifying the current synchronization context enables the
// action to run on the user-interface thread.
var toggleCheckBox = new ActionBlock<CheckBox>(checkBox =>
{
checkBox.Checked = !checkBox.Checked;
},
new ExecutionDataflowBlockOptions
{
TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
});
// Create a ConcurrentExclusiveSchedulerPair object.
// Readers will run on the concurrent part of the scheduler pair.
// The writer will run on the exclusive part of the scheduler pair.
var taskSchedulerPair = new ConcurrentExclusiveSchedulerPair();
// Create an ActionBlock<int> object for each reader CheckBox object.
// Each ActionBlock<int> object represents an action that can read
// from a resource in parallel to other readers.
// Specifying the concurrent part of the scheduler pair enables the
// reader to run in parallel to other actions that are managed by
// that scheduler.
var readerActions =
from checkBox in new CheckBox[] {checkBox1, checkBox2, checkBox3}
select new ActionBlock<int>(milliseconds =>
{
// Toggle the check box to the checked state.
toggleCheckBox.Post(checkBox);
// Perform the read action. For demonstration, suspend the current
// thread to simulate a lengthy read operation.
Thread.Sleep(milliseconds);
// Toggle the check box to the unchecked state.
toggleCheckBox.Post(checkBox);
},
new ExecutionDataflowBlockOptions
{
TaskScheduler = taskSchedulerPair.ConcurrentScheduler
});
// Create an ActionBlock<int> object for the writer CheckBox object.
// This ActionBlock<int> object represents an action that writes to
// a resource, but cannot run in parallel to readers.
// Specifying the exclusive part of the scheduler pair enables the
// writer to run in exclusively with respect to other actions that are
// managed by the scheduler pair.
var writerAction = new ActionBlock<int>(milliseconds =>
{
// Toggle the check box to the checked state.
toggleCheckBox.Post(checkBox4);
// Perform the write action. For demonstration, suspend the current
// thread to simulate a lengthy write operation.
Thread.Sleep(milliseconds);
// Toggle the check box to the unchecked state.
toggleCheckBox.Post(checkBox4);
},
new ExecutionDataflowBlockOptions
{
TaskScheduler = taskSchedulerPair.ExclusiveScheduler
});
// Link the broadcaster to each reader and writer block.
// The BroadcastBlock<T> class propagates values that it
// receives to all connected targets.
foreach (var readerAction in readerActions)
{
broadcaster.LinkTo(readerAction);
}
broadcaster.LinkTo(writerAction);
// Start the timer.
timer1.Start();
}
// Event handler for the timer.
private void timer1_Tick(object sender, EventArgs e)
{
// Post a value to the broadcaster. The broadcaster
// sends this message to each target.
broadcaster.Post(1000);
}
}
}
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Threading.Tasks.Dataflow
Namespace WriterReadersWinForms
Partial Public Class Form1
Inherits Form
' Broadcasts values to an ActionBlock<int> object that is associated
' with each check box.
Private broadcaster As New BroadcastBlock(Of Integer)(Nothing)
Public Sub New()
InitializeComponent()
' Create an ActionBlock<CheckBox> object that toggles the state
' of CheckBox objects.
' Specifying the current synchronization context enables the
' action to run on the user-interface thread.
Dim toggleCheckBox = New ActionBlock(Of CheckBox)(Sub(checkBox) checkBox.Checked = Not checkBox.Checked, New ExecutionDataflowBlockOptions With {.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()})
' Create a ConcurrentExclusiveSchedulerPair object.
' Readers will run on the concurrent part of the scheduler pair.
' The writer will run on the exclusive part of the scheduler pair.
Dim taskSchedulerPair = New ConcurrentExclusiveSchedulerPair()
' Create an ActionBlock<int> object for each reader CheckBox object.
' Each ActionBlock<int> object represents an action that can read
' from a resource in parallel to other readers.
' Specifying the concurrent part of the scheduler pair enables the
' reader to run in parallel to other actions that are managed by
' that scheduler.
Dim readerActions = From checkBox In New CheckBox() {checkBox1, checkBox2, checkBox3} _
Select New ActionBlock(Of Integer)(Sub(milliseconds)
' Toggle the check box to the checked state.
' Perform the read action. For demonstration, suspend the current
' thread to simulate a lengthy read operation.
' Toggle the check box to the unchecked state.
toggleCheckBox.Post(checkBox)
Thread.Sleep(milliseconds)
toggleCheckBox.Post(checkBox)
End Sub, New ExecutionDataflowBlockOptions With {.TaskScheduler = taskSchedulerPair.ConcurrentScheduler})
' Create an ActionBlock<int> object for the writer CheckBox object.
' This ActionBlock<int> object represents an action that writes to
' a resource, but cannot run in parallel to readers.
' Specifying the exclusive part of the scheduler pair enables the
' writer to run in exclusively with respect to other actions that are
' managed by the scheduler pair.
Dim writerAction = New ActionBlock(Of Integer)(Sub(milliseconds)
' Toggle the check box to the checked state.
' Perform the write action. For demonstration, suspend the current
' thread to simulate a lengthy write operation.
' Toggle the check box to the unchecked state.
toggleCheckBox.Post(checkBox4)
Thread.Sleep(milliseconds)
toggleCheckBox.Post(checkBox4)
End Sub, New ExecutionDataflowBlockOptions With {.TaskScheduler = taskSchedulerPair.ExclusiveScheduler})
' Link the broadcaster to each reader and writer block.
' The BroadcastBlock<T> class propagates values that it
' receives to all connected targets.
For Each readerAction In readerActions
broadcaster.LinkTo(readerAction)
Next readerAction
broadcaster.LinkTo(writerAction)
' Start the timer.
timer1.Start()
End Sub
' Event handler for the timer.
Private Sub timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles timer1.Tick
' Post a value to the broadcaster. The broadcaster
' sends this message to each target.
broadcaster.Post(1000)
End Sub
End Class
End Namespace