Parametry i wartości zwracane w przypadku procedur wielowątkowej (C# i Visual Basic)
Dostarczanie i zwracanie wartości w wielowątkowych aplikacji jest skomplikowane, ponieważ konstruktora dla klasy wątek musi być przekazany odniesienie do procedury, która nie przyjmuje żadnych argumentów i zwraca wartość nie.W poniższych sekcjach przedstawiono kilka prostych sposobów dostaw parametrów i procedur otrzymywania wartości w osobnych wątkach.
Dostarczanie parametry procedury wielowątkowe
Najlepszym sposobem dostaw parametry wywołania metody wielowątkowe jest otaczanie metody docelowej w klasie i definiowania pól dla tej klasy, który będzie służyć jako parametry dla nowego wątku.Zaletą tego podejścia jest to, że można utworzyć nową instancję klasy, z własnej parametry za każdym razem, gdy chcesz rozpocząć nowy wątek.Załóżmy na przykład, funkcji, która oblicza powierzchnię trójkąta, jak w poniższym kodzie:
Function CalcArea(ByVal Base As Double, ByVal Height As Double) As Double
CalcArea = 0.5 * Base * Height
End Function
double CalcArea(double Base, double Height)
{
return 0.5 * Base * Height;
}
Można napisać klasa, która otacza CalcArea funkcję i tworzy pola do przechowywania parametrów wejściowych w następujący sposób:
Class AreaClass
Public Base As Double
Public Height As Double
Public Area As Double
Sub CalcArea()
Area = 0.5 * Base * Height
MessageBox.Show("The area is: " & Area.ToString)
End Sub
End Class
class AreaClass
{
public double Base;
public double Height;
public double Area;
public void CalcArea()
{
Area = 0.5 * Base * Height;
MessageBox.Show("The area is: " + Area.ToString());
}
}
Aby użyć AreaClass, można utworzyć AreaClass obiekt, a następnie ustaw Base i Height właściwości, jak pokazano w poniższym kodzie:
Protected Sub TestArea()
Dim AreaObject As New AreaClass
Dim Thread As New System.Threading.Thread(
AddressOf AreaObject.CalcArea)
AreaObject.Base = 30
AreaObject.Height = 40
Thread.Start()
End Sub
protected void TestArea()
{
AreaClass AreaObject = new AreaClass();
System.Threading.Thread Thread =
new System.Threading.Thread(AreaObject.CalcArea);
AreaObject.Base = 30;
AreaObject.Height = 40;
Thread.Start();
}
Warto zauważyć, że TestArea procedury nie sprawdza wartość Area pola po wywołaniu CalcArea metody.Ponieważ CalcArea jest uruchamiany w osobnym wątku, Area pole nie jest gwarantowane, aby ustawić, jeśli użytkownik sprawdza natychmiast po wywołaniu Thread.Start.Następnej sekcji omówiono lepszy sposób do zwracania wartości z procedur wielowątkowe.
Zwracanie wartości z procedur wielowątkowe
Zwracanie wartości z procedur, które są uruchamiane w osobnych wątkach jest skomplikowana przez fakt, że procedury nie może być funkcji i nie można używać ByRef argumentów.Najprostszym sposobem zwracają wartości jest użycie BackgroundWorker składnika do zarządzania swoje wątki i podnieść zdarzenie, kiedy zadanie jest wykonywane i przetworzenia wyników z obsługą zdarzeń.
Poniższy przykład zwraca wartość poprzez podnoszenie zdarzenia z procedury uruchomione w osobnym wątku:
Private Class AreaClass2
Public Base As Double
Public Height As Double
Function CalcArea() As Double
' Calculate the area of a triangle.
Return 0.5 * Base * Height
End Function
End Class
Private WithEvents BackgroundWorker1 As New System.ComponentModel.BackgroundWorker
Private Sub TestArea2()
Dim AreaObject2 As New AreaClass2
AreaObject2.Base = 30
AreaObject2.Height = 40
' Start the asynchronous operation.
BackgroundWorker1.RunWorkerAsync(AreaObject2)
End Sub
' This method runs on the background thread when it starts.
Private Sub BackgroundWorker1_DoWork(
ByVal sender As Object,
ByVal e As System.ComponentModel.DoWorkEventArgs
) Handles BackgroundWorker1.DoWork
Dim AreaObject2 As AreaClass2 = CType(e.Argument, AreaClass2)
' Return the value through the Result property.
e.Result = AreaObject2.CalcArea()
End Sub
' This method runs on the main thread when the background thread finishes.
Private Sub BackgroundWorker1_RunWorkerCompleted(
ByVal sender As Object,
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs
) Handles BackgroundWorker1.RunWorkerCompleted
' Access the result through the Result property.
Dim Area As Double = CDbl(e.Result)
MessageBox.Show("The area is: " & Area.ToString)
End Sub
class AreaClass2
{
public double Base;
public double Height;
public double CalcArea()
{
// Calculate the area of a triangle.
return 0.5 * Base * Height;
}
}
private System.ComponentModel.BackgroundWorker BackgroundWorker1
= new System.ComponentModel.BackgroundWorker();
private void TestArea2()
{
InitializeBackgroundWorker();
AreaClass2 AreaObject2 = new AreaClass2();
AreaObject2.Base = 30;
AreaObject2.Height = 40;
// Start the asynchronous operation.
BackgroundWorker1.RunWorkerAsync(AreaObject2);
}
private void InitializeBackgroundWorker()
{
// Attach event handlers to the BackgroundWorker object.
BackgroundWorker1.DoWork +=
new System.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork);
BackgroundWorker1.RunWorkerCompleted +=
new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted);
}
private void BackgroundWorker1_DoWork(
object sender,
System.ComponentModel.DoWorkEventArgs e)
{
AreaClass2 AreaObject2 = (AreaClass2)e.Argument;
// Return the value through the Result property.
e.Result = AreaObject2.CalcArea();
}
private void BackgroundWorker1_RunWorkerCompleted(
object sender,
System.ComponentModel.RunWorkerCompletedEventArgs e)
{
// Access the result through the Result property.
double Area = (double)e.Result;
MessageBox.Show("The area is: " + Area.ToString());
}
Można podać parametry i zwracają wartości do wątku puli wątków, przy użyciu opcjonalnej ByVal obiekt stanu zmiennej QueueUserWorkItem metody.Wątki wątku czasomierza obsługują także obiekt stanu dla tego celu.Informacje dotyczące puli wątków i czasomierzy wątku, zobacz Wątek puli (C# i Visual Basic) i Wątek czasomierze (C# i Visual Basic).
Zobacz też
Zadania
Instruktaż: Wielowątkowość ze składnikiem BackgroundWorker (C# i Visual Basic)
Informacje
Wątek synchronizacji (C# i Visual Basic)
Zdarzenia (Podręcznik programowania C#)
Pełnomocnicy (Podręcznik programowania C#)
Koncepcje
Wątek puli (C# i Visual Basic)
Aplikacje wielowątkowe (C# i Visual Basic)