views:

61

answers:

1

Hi all,


EDIT: Issue worked around. This Console code was testing for ultimate use in a WPF app. I've moved the code to a WPF test app and it works, slightly modified of course. So I'll leave this Console issue, as at the end of the day it's not actually important!

I'm basically trying to call "Console.ReadLine()" from an asynch method. The Console call is actually 'embedded' in a delegate method to allow external interaction. Prob: The app crashes when I hit enter at the Console prompt. Make sense? Here's another attempt to explain...

Situation: - Console app.
- There's a class, 'C', with a method that runs asynch.
- The class takes a delegate 'd' in the constructor.
- The method added to the delegate reads console input
* After entering the input and hitting enter, the app seems to just die. :-(

Something like:

C c = new C(d);  //  d is the delegate, holding a single method which calls Console.ReadLine()  
c.DoYourStuffAsynch(); // DoYourStuffAsynch(), among other things calls d.Invoke()  

At the moment, as mentioned above, the app seems to just die after pressing the enter key to enter the Console input. I guess this is a threading issue, but I can write to the Console okay with this set up!

BTW The reason for the call is to allow the calling code to request user permission in what ever form it wishes, returning a Go/NoGO bool.

If you survived that, any ideas? Getting stuck on issues like this kind of sucks, so thanks in advance for any help! :-)

EDIT: Here's some code, as requested (too much?!). Actually it's the entire update testing app - a Console app using my (WIP) UpdateWrapper class.

CODE PART I: UpdateWrapper class. The delegate invocation is in deployment_CheckForUpdateCompleted() under "// DOWNLOAD THE UPDATE" near the bottom.

delegate bool PermissionDelegate();

class UpdateWrapper
{
    #region
    //  the ApplicationDeployment class is used to do check and download ClickOnce updates
    ApplicationDeployment deployment = null;
    PermissionDelegate userHasOKedUpdate = null;

    //  for a spot of time-keeping
    private System.Diagnostics.Stopwatch sw = null;
    #endregion

    #region Ctors
    /// <summary>
    /// A default ctor
    /// </summary>
    public UpdateWrapper(PermissionDelegate usersHasOKedUpdate)
    {
        //  assign members
        deployment = ApplicationDeployment.CurrentDeployment;
        this.userHasOKedUpdate = usersHasOKedUpdate;

        //  assign update event handlers
        deployment.CheckForUpdateCompleted += new CheckForUpdateCompletedEventHandler(deployment_CheckForUpdateCompleted);
        deployment.UpdateCompleted += new System.ComponentModel.AsyncCompletedEventHandler(deployment_UpdateCompleted);
    }
    #endregion

    /// <summary>
    /// Initiates the updating process by checking whether an update exists. Events control the flow from there.
    /// </summary>
    public void CheckForUpdateAsynch()
    {
        Console.WriteLine("Checking for updates...OO from " + deployment.UpdateLocation.ToString());

        //
        //  CHECK WHETHER THE APP IS NETWORK DEPLOYED. If not, ClickOnce updating can't work.
        //  No? Return.
        //
        bool notNetworkDeployedSoCannotCheckForUpdates = !ApplicationDeployment.IsNetworkDeployed;
        if (notNetworkDeployedSoCannotCheckForUpdates)
        {
            Console.WriteLine("The app is not network deployed! OO");
            return;
        }
        else
        {
            Console.WriteLine("Network deployed. OO");
        }


        //
        //  CHECK WHETHER THERE'S AN UPDATE AVAILABLE, asynchronously
        //  No? Return.
        //
        try  //  to see if there's an update
        {
            //  attempt to retrieve any updates
            Console.WriteLine("Checking for a detailed update now via OO, asyncronously.");
            deployment.CheckForUpdateAsync();
        }
        catch (Exception ex)
        {
            throw new Exception("Problem checking for OO updates: " + ex.Message + Environment.NewLine);
        }
    }

    #region Updating Event-Handlers
    /// <summary>
    /// Responds to when an asynch update check completes.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void deployment_CheckForUpdateCompleted(object sender, CheckForUpdateCompletedEventArgs e)
    {
        //
        //  CHECK FOR UPDATE ERRORS
        //  Errors? Return
        bool errorOccurredWhileCheckingForUpdates = e.Error != null;
        if (errorOccurredWhileCheckingForUpdates)
        {
            Console.WriteLine("An error has been reported while checking for updates.");
            return;
        }
        else
        {
            Console.WriteLine("Update check is error-free");
        }

        //
        //  CHECK IF UPDATE IS AVAILABLE
        //  No? Return
        bool anUpdateIsAvailable = e.UpdateAvailable;
        if (anUpdateIsAvailable)
        {
            Console.WriteLine("Yeah, an update is available!");
        }
        else
        {
            Console.WriteLine("No update available.");
            return;
        }

        //
        //  DOWNLOAD THE UPDATE
        //
        try
        {
            Console.WriteLine("About to call your usersHasOKedUpdate() method!");

            bool proceed = userHasOKedUpdate.Invoke();
            if (proceed)
            {
                deployment.UpdateAsync();
            }
            else
            {
                Console.WriteLine("Your user declined the update!");
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine("There was an error while updating asynch: " + ex.Message);
        }
    }

    /// <summary>
    ///Responds to when a new version has been downloaded. 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void deployment_UpdateCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        //
        //  CHECK FOR PROCESS ERRORS
        //  Errors? Return.
        bool errorsOccurredWhileDownloadingUpdate = e.Error != null;
        if (errorsOccurredWhileDownloadingUpdate)
        {
            Console.WriteLine("An error has been reported while installing the update. OO");
            return;
        }
        else
        {
            Console.WriteLine("The update seems to have been installed okay. Restart the app! OO");
        }
    }
    #endregion
}

CODE Part II: The console app. The method added to the delegate is GetUpdateGoAhead() at the bottom. That's where the call to ReadLine() is. Note that Console.WriteLine() calls work fine here. Hitting Enter for the ReadLine() seems to immediately kill the app.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OOUpdateTester
{
class Program
{
    /// <summary>
    /// App entry
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
        Program p = new Program();
        p.Start();
    }

    private string version = "Beta 2.7";

    /// <summary>
    /// Simply tries to update this app
    /// </summary>
    public void Start()
    {
        Console.WriteLine("Program underway (version " + version + ")");

        UpdateTester.PermissionDelegate updatePermissionCarrier = new UpdateTester.PermissionDelegate(GetUpdateGoAhead);
        UpdateTester.UpdateWrapper updater = new UpdateTester.UpdateWrapper(updatePermissionCarrier);

        try
        {
            Console.WriteLine("Getting the updater to update...");
            updater.CheckForUpdateAsynch();
            Console.WriteLine(" - seems okay");
        }
        catch (Exception ex)
        {
            Console.WriteLine("The updater object thru an error: " + ex.Message);
        }
        finally
        {
            Console.WriteLine("Holding...");
            Console.ReadLine();
        }

    }

    /// <summary>
    /// Returns true if the user okays the updating.
    /// </summary>
    /// <returns></returns>
    private bool GetUpdateGoAhead()
    {
        try
        {
            Console.WriteLine("An update is available. Update? Y/N ");
            string reply = Console.ReadLine();
            bool proceed = reply.StartsWith("Y");

            if (proceed)
            {
                Console.WriteLine(" - answer YES");
                return true;
            }

            Console.WriteLine(" - answer NO");
            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error from delegate method: " + ex.Message);
            throw ex;
        }

    }
}

}

A: 

Edited cos I was talking crap :)

chrisb
You mentioned using events, and that was the other option I'd considered. I'm not sure if there would be threading issues there too, but I'll try it anyway. Thanks for the reply!
Gregg Cleland