0

I'm tasked with creating a tool to help set up customers systems easily. I've created a function that calls a chocolatey script through powershell in c# and I use Task.run to create a new thread so it doesn't affect the UI thread, The system works fine, but I'm having problems with some computers. It's not helped that I have no access to these computers and do not know much about their system, and due to time constraints do not have access to these computers. I do know they have windows 8.1. I was given a windows 10 virtual machine to test on (which I still don't understand as it was known that this was a windows 8 problem)

Here is the code. I know for a fact(due to the one time I was given access to these computers) that it stops on Task.Run(() => task)

Does anyone know if there are any problems with either chocolatey or Tasks on windows 8.1?

Task callTask = Task.Run(() => ExecuteAsynchronouslyAsync("chocolatey string", CheckBox box, string logName));

public async Task<PowerShellAction> ExecuteAsynchronouslyAsync(String commandStr, CheckBox box, string logName)
{
    powerShellAction = new PowerShellAction();
    powerShellAction.isFinished = false;
    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddScript(commandStr); // adding the script to the powershell script.
        outputCollection = new PSDataCollection<PSObject>();
        outputCollection.DataAdded += OutputData;
        IAsyncResult result = ps.BeginInvoke<PSObject, PSObject>(null, outputCollection);
        PSDataCollection<PSObject> execRes = await Task.Factory.FromAsync(result, ps.EndInvoke);
    }
    return powerShellAction;
}

Working right now on trying to get a virtual machine of 8.1 to continue trying to debug myself. Any other suggestions would be welcome.

Alexander Schmidt
  • 5,631
  • 4
  • 39
  • 79
Holly Plyler
  • 339
  • 2
  • 10

1 Answers1

1

Unfortunately I cannot ensure that my suggestions are correct. The main reason is, that i can't figure out what PowerShellAction is supposed to be. I'm assuming here that PowerShell is System.Management.Automation.PowerShell.

I'm suggesting several things:

  1. Your code does not compile for several reasons: you have no var or type-declaration on the first line of your method and the method-call would not work because of the addition string keyword. Try to avoid pasting in code like yours in the future please because it's pretty hard to rebuild your sample.
  2. Don't bypass a UI control to an async method but use the needed value (e.g. box.IsChecked as a bool) instead.
  3. Add ConfigureAwait(false) to your await to prevent .NET from trying to sync back to the context.
  4. Take more care about exception handling insude of your method.
  5. Dont' return anything if you don't need it in your method.

The code (untestet) could be something like this:

var task = Task.Run(() => ExecutePowerShellAsync("chocolatey string", box.IsChecked, "NameOfTheLog"));

public async Task<PowerShellAction> ExecutePowerShellAsync(String commandStr, bool checkBoxValue, string logName)
{
    var powerShellAction = new PowerShellAction();
    powerShellAction.isFinished = false;
    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddScript(commandStr); // adding the script to the powershell script.
        var outputCollection = new PSDataCollection<PSObject>();
        outputCollection.DataAdded += OutputData;
        IAsyncResult result = ps.BeginInvoke<PSObject, PSObject>(null, outputCollection);
        PSDataCollection<PSObject> execRes = await Task.Factory.FromAsync(result, ps.EndInvoke).ContinueWith(t => {
            if (t.IsFaulted) 
            {
                System.Diagnostics.Trace.TraceError("Task faulted with exception: " + t.Exception?.Message);    
            }
            return t.Result;
        }).ConfigureAwait(false);
    }
    return powerShellAction;
}

I use ContinueWith in order to be able to react to any exception that might occur inside the original task.

I'm suggesting this because your description smells like you have a typical thread-lock which means the code simple does not come back due to an exception or context-syncing-problems.

Alexander Schmidt
  • 5,631
  • 4
  • 39
  • 79
  • Yes, I've got hands on one of the computers with the problem. It's definately a thread problem. The computer in question only has 4 threads, so I'll need to figure out some optimization. Thank you for your reply. – Holly Plyler Jan 07 '19 at 23:33
  • 1
    Ok good. Go ahead and try my suggestions then. Should bring you nearer to the problem at leadt. – Alexander Schmidt Jan 07 '19 at 23:36
  • 1
    I've gotten it working on the lowest common denominator. I took away the gui for now and made it a console app, (one less thread to worry about) took away the task.run bits and it works. I'll continue refactoring code so I can get the gui back eventually, but this should help our techs for now. – Holly Plyler Jan 08 '19 at 19:01