/// <summary>
        /// Asynchroner Start eines "langlaufenden" WCF- Dienstes. Das Ende des Dienstes muß explizit durch Drücken
        /// des Buttons "btnFertig" sichergestellt werden.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBegin_Click(object sender, EventArgs e)
        {
            try
            {
                if (callingProxy != null && callingProxy.State != System.ServiceModel.CommunicationState.Closed)
                    throw new Exception("Es wurde bereits ein langlaufender Dienst gestartet. Dieser muß zunächst mit \"Fertig\" beendet werden");

                callingProxy = new CallingPatternsRef.CallingPatternsClient();

                int delay;
                if (int.TryParse(tbxLongRunningOpMinExecTime.Text, out delay))
                {
                    lblResultDelaydStart.Text = DateTime.Now.ToString("T");
                    log.Log(mko.Log.RC.CreateStatus("Asynchrone Ausführung der Langläuferop startet [" + tbxLongRunningOpMinExecTime.Text + " ms]. Bitte \"Fertig\" anklicken!"));
                    aresDeleayedReturn = callingProxy.BeginDelayedReturn(delay, null, null);

                    progressBarLongRunningOp.Minimum = 0;
                    progressBarLongRunningOp.Maximum = 100;
                    progressBarLongRunningOp.Value = 0;

                    CallingPatternsAnimationTimer.Start();
                }
            }
            catch (Exception ex)
            {
                log.Log(mko.Log.RC.CreateError("Beim asynchronen Start eines WCF- Dienstes: " + ex.Message));
            }
        }
        //----------------------------------------------------------------------------------------------------------
        // Ü: Aufruf von Methoden synchron als auch asynchron

        /// <summary>
        /// Synchroner Start einer WCF- Operation: Der Client blockiert solange, bis der WCF- Dienst auf dem Server
        /// beendet wurde.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLongRunningOpStartSync_Click(object sender, EventArgs e)
        {
            try
            {
                using (var proxy = new CallingPatternsRef.CallingPatternsClient())
                {
                    int delay;
                    if (int.TryParse(tbxLongRunningOpMinExecTime.Text, out delay))
                    {
                        lblSyncStart.Text = DateTime.Now.ToString("T");
                        lblResultSyncReturn.Text = "";
                        log.Log(mko.Log.RC.CreateStatus("Synchrone Ausführung der Langläuferop startet [" + tbxLongRunningOpMinExecTime.Text + " ms]"));

                        proxy.DelayedReturn(delay);

                        lblResultSyncReturn.Text = DateTime.Now.ToString("T");

                        log.Log(mko.Log.RC.CreateStatus("Synchrone Ausführung der Langläufermehtode beendet"));
                    }
                    else
                    {
                        log.Log(mko.Log.RC.CreateError("Die Eingabe für die Verzögerungszeit ist unkorrekt"));
                    }
                }
            }
            catch (Exception ex)
            {
                log.Log(mko.Log.RC.CreateError(ex.Message));
            }
        }
 /// <summary>
 /// Asynchroner Start eines langlaufenden WCF- Dienstes. Wenn der Dienst endete, dann wird auf dem Client
 /// eine Callback- Methode gestartet. Diese ruft das Ergebnis des Dienstes ab und aktualisiert damit Steuer-
 /// elemente in der GUI des Client. Dabei muß berücksichtigt werden, daß GUI- Steuerelemente nur aus dem
 /// UI- Thread heraus aktualisiert werden dürfen
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void btnDeleayedReturnAsyncCallback_Click(object sender, EventArgs e)
 {
     try
     {
         int delay;
         if (int.TryParse(tbxLongRunningOpMinExecTime.Text, out delay))
         {
             callingProxy       = new CallingPatternsRef.CallingPatternsClient();
             aresDeleayedReturn = callingProxy.BeginDelayedReturn(delay, new AsyncCallback(CallBackDelayedReturn), null);
         }
     }
     catch (Exception ex)
     {
         log.Log(mko.Log.RC.CreateError("Beim Starten eines asynchronen WCF- Dienstes mit Callback: " + ex.Message));
     }
 }
        /// <summary>
        /// Asynchronder Aufruf einer WCF- Operation: Der Client wird unmittelbar nach dem Aufruf der WCF- Methode
        /// fortgesetzt. Durch Polling wird das Ende der Operation bestimmt. Während des Pollings wird die 
        /// verstrichene Zeit durch einen Progress- Bar dargestellt, und die Verarbeitung weiterer GUI- Ereignisse ermöglicht,
        /// um ein "Einfrieren" wie beim synchronen Start zu vermeiden
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLongRunningOpStartAsync_Click(object sender, EventArgs e)
        {
            try
            {
                using (var proxy = new CallingPatternsRef.CallingPatternsClient())
                {
                    int delay;
                    if (int.TryParse(tbxLongRunningOpMinExecTime.Text, out delay))
                    {
                        log.Log(mko.Log.RC.CreateStatus("Asynchrone Ausführung der Langläuferop startet [" + tbxLongRunningOpMinExecTime.Text + " ms]"));
                        progressBarLongRunningOp.Minimum = 0;
                        progressBarLongRunningOp.Maximum = delay;
                        progressBarLongRunningOp.Value = 0;

                        IAsyncResult ares = proxy.BeginDelayedReturn(delay, null, null);


                        long oldTicks = DateTime.Now.Ticks;

                        while (!ares.IsCompleted)
                        {
                            Application.DoEvents();

                            long now = DateTime.Now.Ticks;
                            int diff = (int)(now - oldTicks) / 10000;
                            progressBarLongRunningOp.Value = Math.Min(diff, progressBarLongRunningOp.Maximum);

                        }

                        log.Log(mko.Log.RC.CreateStatus("Asynchrone Ausführung der Langläufermehtode beendet"));
                    }
                    else
                    {
                        log.Log(mko.Log.RC.CreateError("Die Eingabe für die Verzögerungszeit ist unkorrekt"));
                    }
                }
            }
            catch (Exception ex)
            {
                log.Log(mko.Log.RC.CreateError(ex.Message));
            }

        }