mirror of
https://github.com/skoelle/buildbroken-blog-archive.git
synced 2026-09-18 02:40:24 +00:00
fix code blocks
This commit is contained in:
+60
-119
@@ -42,25 +42,25 @@ Der Code hinter der UI sieht folgendermaßen aus. Beim instanziieren des Forms,
|
||||
|
||||
Bei dem Drücken des „Run“-Buttons, wird die Methode Calculator.CalcAsync(…) aufgerufen.
|
||||
|
||||
```
|
||||
public partial class Form1 : Form {
|
||||
private ICalculator m_calculator;
|
||||
public Form1() {
|
||||
InitializeComponent();
|
||||
m_calculator = new Calculator ();
|
||||
m_calculator.CalcCompleted += Calculator_CalcCompleted;
|
||||
}
|
||||
```csharp
|
||||
public partial class Form1 : Form {
|
||||
private ICalculator m_calculator;
|
||||
public Form1() {
|
||||
InitializeComponent();
|
||||
m_calculator = new Calculator();
|
||||
m_calculator.CalcCompleted += Calculator_CalcCompleted;
|
||||
}
|
||||
|
||||
private void Run_Click( object sender, EventArgs e) {
|
||||
int number;
|
||||
if ( Int32 .TryParse(txbEingabe.Text, out number)) {
|
||||
m_calculator.CalcAsync(number, number);
|
||||
}
|
||||
}
|
||||
private void Run_Click(object sender, EventArgs e) {
|
||||
int number;
|
||||
if (Int32.TryParse(txbEingabe.Text, out number)) {
|
||||
m_calculator.CalcAsync(number, number);
|
||||
}
|
||||
}
|
||||
|
||||
void Calculator_CalcCompleted( object sender, CalcEventArgs eventArgs) {
|
||||
lblCounter.Text = eventArgs.Result.ToString();
|
||||
}
|
||||
void Calculator_CalcCompleted(object sender, CalcEventArgs eventArgs) {
|
||||
lblCounter.Text = eventArgs.Result.ToString();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -68,119 +68,60 @@ Sobald die Berechnung fertig ist, wird das CalcCompleted-Event ausgelöst und so
|
||||
|
||||
Der Calculator sieht wie folgt aus:
|
||||
|
||||
```
|
||||
public interface ICalculator {
|
||||
event Calculator . CalcCompletedEventHandler CalcCompleted;
|
||||
int Calc( int number);
|
||||
void CalcAsync( int number, object userState);
|
||||
```csharp
|
||||
public interface ICalculator {
|
||||
event Calculator.CalcCompletedEventHandler CalcCompleted;
|
||||
int Calc(int number);
|
||||
void CalcAsync(int number, object userState);
|
||||
}
|
||||
|
||||
public class Calculator : ICalculator {
|
||||
public delegate void CalcCompletedEventHandler ( object sender, CalcEventArgs eventArgs);
|
||||
public event CalcCompletedEventHandler CalcCompleted;
|
||||
private AsyncOperation m_asyncOperation;
|
||||
private bool m_isRunning;
|
||||
public class Calculator : ICalculator {
|
||||
public delegate void CalcCompletedEventHandler(object sender, CalcEventArgs eventArgs);
|
||||
public event CalcCompletedEventHandler CalcCompleted;
|
||||
private AsyncOperation m_asyncOperation;
|
||||
private bool m_isRunning;
|
||||
|
||||
public int Calc( int number) {
|
||||
Thread .Sleep(10000);
|
||||
return number * number;
|
||||
public int Calc(int number) {
|
||||
Thread.Sleep(10000);
|
||||
return number * number;
|
||||
}
|
||||
|
||||
public void CalcAsync(int number, object userState) {
|
||||
lock (this) {
|
||||
if (m_isRunning) {
|
||||
throw new InvalidOperationException("Diese Operation wird bereits ausgeführt");
|
||||
}
|
||||
m_isRunning = true;
|
||||
m_asyncOperation = AsyncOperationManager.CreateOperation(userState);
|
||||
ThreadPool.QueueUserWorkItem(ExecuteCalc, number);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteCalc(object state) {
|
||||
int result = Calc((int)state);
|
||||
m_asyncOperation.PostOperationCompleted(CalcCompletedSuccessful, result);
|
||||
}
|
||||
|
||||
private void CalcCompletedSuccessful(object result) {
|
||||
if (CalcCompleted != null) {
|
||||
CalcCompleted(this, new CalcEventArgs(null, false, (int)result, result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CalcAsync( int number, object userState) {
|
||||
lock ( this ) {
|
||||
if (m_isRunning) {
|
||||
throw new InvalidOperationException ( "Diese Operation wird bereits ausgeführt" );
|
||||
}
|
||||
m_isRunning = true ;
|
||||
m_asyncOperation = AsyncOperationManager .CreateOperation(userState);
|
||||
ThreadPool .QueueUserWorkItem(ExecuteCalc, number);
|
||||
}
|
||||
public class CalcEventArgs : AsyncCompletedEventArgs {
|
||||
public CalcEventArgs(Exception error, bool cancelled, int result, object userState)
|
||||
: base(error, cancelled, userState) {
|
||||
Result = result;
|
||||
}
|
||||
public int Result { get; private set; }
|
||||
}
|
||||
```
|
||||
|
||||
.
|
||||
|
||||
.
|
||||
|
||||
.
|
||||
|
||||
```
|
||||
}
|
||||
```
|
||||
|
||||
Wie man im Interface des Calculator sieht, gibt es eine synchrone und eine asynchrone Methode für die Berechnung. Uns interessiert allerdings nur die asynchrone Methode. Das lock und die Prüfung auf m\_isRunning verhindern lediglich, dass die asynchrone Methode während ihrer Ausführung öfter aufgerufen wird. Das Wesentliche an dieser Methode ist der Aufruf von AsyncOperationManager.CreateOperation, denn dieser Aufruf stellt einen Synchronisationskontext bereit, der die Threads miteinander synchronisiert. Für die eigentliche Berechnung wird sich über den ThreadPool ein neuer Thread besorgt, der sich dann um die Abarbeitung der ExecuteCalc in einem eigenen Thread kümmert.
|
||||
|
||||
```
|
||||
public class Calculator : ICalculator {
|
||||
```
|
||||
|
||||
.
|
||||
|
||||
.
|
||||
|
||||
.
|
||||
|
||||
```
|
||||
private void ExecuteCalc( object state) {
|
||||
int result = Calc(( int )state);
|
||||
m_asyncOperation.PostOperationCompleted(CalcCompletedSuccessful, result);
|
||||
}
|
||||
|
||||
private void CalcCompletedSuccessful( object result) {
|
||||
if (CalcCompleted != null ) {
|
||||
CalcCompleted( this , new CalcEventArgs ( null , false , ( int )result, result));
|
||||
}
|
||||
}
|
||||
}
|
||||
public class CalcEventArgs : AsyncCompletedEventArgs {
|
||||
public CalcEventArgs( Exception error, bool cancelled, int result, object userState)
|
||||
: base (error, cancelled, userState) {
|
||||
Result = result;
|
||||
}
|
||||
public int Result { get ; private set ; }
|
||||
}
|
||||
```
|
||||
Wie man im Interface des Calculator sieht, gibt es eine synchrone und eine asynchrone Methode für die Berechnung. Uns interessiert allerdings nur die asynchrone Methode. Das lock und die Prüfung auf m\_isRunning verhindern lediglich, dass die asynchrone Methode während ihrer Ausführung öfter aufgerufen wird. Das Wesentliche an dieser Methode ist der Aufruf von AsyncOperationManager.CreateOperation, denn dieser Aufruf stellt einen Synchronisationskontext bereit, der die Threads miteinander synchronisiert. Für die eigentliche Berechnung wird sich über den ThreadPool ein neuer Thread besorgt, der sich dann um die Abarbeitung der ExecuteCalc in einem eigenen Thread kümmert.
|
||||
|
||||
Sobald die Berechnung abgeschlossen ist, wird der Thread mit dem MainThread über den Aufruf von PostOperationCompleted synchronisiert und das CalcCompleted-Event ausgelöst und das Ergebnis in das Label geschrieben (s. o.).
|
||||
|
||||
6 public partial class Form1 : Form {
|
||||
|
||||
7 private ICalculator m\_calculator;
|
||||
|
||||
8 public Form1() {
|
||||
|
||||
9 InitializeComponent();
|
||||
|
||||
10 m\_calculator = new Calculator();
|
||||
|
||||
11 m\_calculator.CalcCompleted += Calculator\_CalcCompleted;
|
||||
|
||||
12 }
|
||||
|
||||
13
|
||||
|
||||
14 private void Run\_Click(object sender, EventArgs e) {
|
||||
|
||||
15 int number;
|
||||
|
||||
16 if (Int32.TryParse(txbEingabe.Text, out number)) {
|
||||
|
||||
17 m\_calculator.CalcAsync(number, number);
|
||||
|
||||
18 }
|
||||
|
||||
19 }
|
||||
|
||||
20
|
||||
|
||||
21 void Calculator\_CalcCompleted(object sender, CalcEventArgs eventArgs) {
|
||||
|
||||
22 lblCounter.Text = eventArgs.UserState.ToString();
|
||||
|
||||
23 }
|
||||
|
||||
24 }
|
||||
|
||||
## Kommentare (Archiv)
|
||||
|
||||
1. <img src="/images/async/3e7b6cb163ea9cc8549abcb8b5a03e2e.jpeg" width="32" height="32" class="avatar avatar-32 photo" alt="Avatar"/> **[Ralf Westphal](http://ralfw.blogspot.com/)**
|
||||
|
||||
Reference in New Issue
Block a user