On Jan 31, 11:39*pm, thoward37 <thowar...@xxxxxx> wrote:
Quote:
> Hi all, this is a follow-up to an earlier post I made regarding
> embedded Powershell:
>
> http://groups.google.com/group/micro....powershell/br...
>
> In short, I'm hosting Powershell in an app as part of a rules engine,
> using it to repeatedly execute user defined scripts on data provided
> from a database, as one kind of "rule".
>
> The way I initially implemented it was to create a single runspace,
> then create and execute a new pipeline eachtime I needed to execute
> the Powershell rule.
>
> An example rule looks like this:
>
> $dataValue =
> $dataProviders[""SomeRandomSqlData""].GetValue(""SomeValue"");
> $checkValue = $dataProviders[""StaticData""].GetValue(""MaxValue"");
> if ($dataValue -eq $checkValue) { exit 5 } else { exit 0 }
>
> The variable $dataProviders is a dictionary containing various data
> providers that allow the Powershell script to make some decisions
> about some data. It is passed into the Powershell world using a
> statement like ...
> Runspace.SessionStateProxy.SetVariable("dataProviders",
> dataProviders); ... and it's updated each time I execute a pipeline
> with the currently available data.
>
> The exit code of the pipeline is checked to get the result of the
> rule, which is then evaluated by the rest of the rule engine.
>
> So, my previous post I had asked about ways to re-use a single
> pipeline, instead of instantiating a new one everytime, but found that
> was not possible.
>
> Currently, this implementation works, but it's very slow, and there
> are other options available for them to script in via traditional .Net
> languages. Also, this code isn't even in QA at the moment, much less
> released, so it's still a good time to make changes in the design...
>
> Since then, it occured to me that a better way to do this might be as
> such:
>
> 1. Instantiate Runspace
> 2. Pre-load the scripts into the Runspace. Each script defines a
> function for each Powershell rule I'll need to run. The function takes
> the dataProviders variable as a parameter, and returns an integer.
> 3. Obtain delegates to the loaded functions from the Runspace.
> 4. When the rule needs to be executed, just invoke the delegate from
> my C# code.
>
> My intention for getting the delegate to the PS function was to use
> the get-delegate function described here:
>
> http://blogs.msdn.com/powershell/arc...25/678259.aspx
>
> So the c# delegate defintion would look like:
>
> * public delegate int PsRuleDelegate(IDictionary<string,
> IRuleDataProvider> dataProviders);
>
> The user function delegate creation code would look like this (with
> each script definition getting it's own delegate variable):
>
> * .. insert get-delegate code here ..
>
> * $MyRuleDelegate = get-delegate `
> * My.Namespace.PsRuleDelegate *{
> * * * $dataValue =
> $dataProviders[""SomeRandomSqlData""].GetValue(""SomeValue"");
> * * * $checkValue =
> $dataProviders[""StaticData""].GetValue(""MaxValue"");
> * * * if ($dataValue -eq $checkValue) { return 5 } else { return 0 }
> * }
>
> Getting the delegate back from the runspace would look like:
>
> * Runspace.SessionStateProxy.GetVariable("MyRuleDelegate");
>
> So, before I go fiddling with it, and trying to make that happen...
> I'd like to know, is this a viable solution? Will this work? I'll
> probably try it anyway tomorrow, but I'd like to hear what more
> experienced and knowledgable people have to say about this idea.
>
> I'm guessing that I will need to assemble the delgate creation
> function, and all the rule function definitions into a single script,
> which is loaded when the runspace first starts up, then obtain the
> named delegate variables after the runspace loads. Would I then not
> need to run a pipeline? Could those delegates be called directly from
> my C# code without an active pipeline (but with an active runspace?).
>
> I think that would improve the performance considerably, without
> changing too much of what the end user needs to write.
>
> Thanks,
> Troy Hi Troy,
From my understanding of the powershell engine itself, it won't be
possible to get a delegate to a function as such. PowerShell's script
is interpreted and no matter how you invoke it, the creation of a
pipeline to execute it is implicit.
Don't get me wrong though, PowerShell is one of the greatest things
(imho) to come out of Microsoft in the last few years but it truely is
a prototype in the best sense of the word; a proof of concept that has
shown itself to be a resounding success in all the areas of
application it has found itself. We all expect great things from V2 -
an incremental improvement in fuctionality in tandem with a order of
magnitude increase in speed would be a great result I think. The
community has proven itself to be more than capable of filling in the
missing bits (thanks to the excellent extensibility of the product),
but as for core efficiency and speed, well, that's down to Jeffrey's
great team.
- Oisin