Search code examples
c#methodsasync-awaitrefactoringsynchronous

How to combine these two methods (async and non-async) into one?


How can I combine these two methods and put as one...

class DataRulesPSScripts
{
    PowerShell ps = PowerShell.Create();
    
    public IEnumerable<object> RunScriptBlock( ScriptBlock scriptBlock, Dictionary<string, object> scriptParameters )
    {
        var vars = scriptParameters.Select( p => new PSVariable( p.Key, p.Value ) ).ToList();
        return scriptBlock.InvokeWithContext( null, vars );
    }
    
    public async Task<ScriptBlock> CreateScriptBlock( string pSScript )
    {
        ps.AddScript( pSScript );
        var scriptBlock = (await ps.InvokeAsync())[0].BaseObject as ScriptBlock;
        return scriptBlock;
    }
}

these two methods are called in a different class in a different method like this. 'ds' is object for class DataRulesPSScripts

private async Task<IEnumerable<object>> GenerateValuesFromScript( Dictionary<string, EntityProperty> arg, string pwScript )
{
    var pars = new Dictionary<string, object>();
    pars.Add( "_", arg );
    var scriptBlock = await ds.CreateScriptBlock( pwScript );
    var results = ds.RunScriptBlock( scriptBlock, pars ).ToList();
    return results;
}

Solution

  • You can write this:

    public async Task<IEnumerable<object>> CreateAndRunScriptBlock(
      string pSScript, 
      Dictionary<string, object> scriptParameters)
    {
      ps.AddScript(pSScript);
      var scriptBlock = ( await ps.InvokeAsync() )[0].BaseObject as ScriptBlock;
      var vars = scriptParameters.Select(p => new PSVariable(p.Key, p.Value)).ToList();
      return scriptBlock.InvokeWithContext(null, vars);
    }
    

    Usage:

    return ( await ds.CreateAndRunScriptBlock(pwScript, pars) ).ToList();
    

    Alternative:

    var items = await ds.CreateAndRunScriptBlock(pwScript, pars);
    return items.ToList();
    

    Also perhaps the method itself may directly return a list:

    public async Task<List<object>> CreateAndRunScriptBlock(
    {
      ...
      return scriptBlock.InvokeWithContext(null, vars).ToList();
    }
    

    Remark

    GenerateValuesFromScript returns a IEnumerable thus the ToList is theorically useless (in this method).