开发者

Start a new Process that executes a delegate

开发者 https://www.devze.com 2023-02-19 07:16 出处:网络
Is is possible in .NET to execute a method (delegate, static method, whatever) in a child process?System.Diagnostics.Process seems to require an actual filename, meaning that a separate executable is

Is is possible in .NET to execute a method (delegate, static method, whatever) in a child process? System.Diagnostics.Process seems to require an actual filename, meaning that a separate executable is needed.

What I am trying to do is to verify, in a unit test, that an OS resource is cleaned up on process exit. I know that could use CodeDOM or IL generation to cre开发者_StackOverflow社区ate such an assembly and execute it, but the whole point of unit tests is to isolate component parts, not to create complexity. For the same reason, I'd like to avoid a separate assembly altogether.

Ideally, I would do something like:

public static void CreateCounter()
{
    var counter = new PerformanceCounter("category", "counter", "instance");
    counter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
}

[Test]
public void TestResourceDisposal()
{
    // Start child process to execute CreateCounter()
    ...
    // verify the resource is disposed
}


First of all, no, there's no way to do this. I process implies a .exe. This isn't Unix where you can fork a process that's a copy of the parent.

I'd just create a tiny .exe to run. Do you need to run the test with different performance counters? If it works with one, then surely it will work with any of them?


What you are talking about is not a unit test. Interacting with actual (expensive) operating system services violates the basic principle of isolation that unit tests are meant to strive for.

If your intent is to test the code in a more end-to-end fashion, actually interacting with the performance counter and so on, this would be an integration test and should be written in a more "heavy duty" way, i.e. writing a separate EXE if needed, running any complex setup or cleanup steps, etc.

If you need to unit test the components that deal with the performance counter, you must first abstract this dependency away. Generally you would create a base class or interface representing the surface area of the performance counter and then create a test double of some sort to replace its functionality at (test) runtime. The real system would use a simple wrapper that delegates to the actual performance counter and would be exercised by integration tests as above.

From reading your comment above, it almost sounds like you are trying to test a guarantee of the .NET framework. I would question whether this is actually necessary as it is quite well tested already, although maybe you want to test that your code is using it properly (in which case you could either do unit or integration testing depending on the verification you are seeking).


I'm not sure exactly what you're trying to accomplish, but would it be easier to return the performance counter instance from CreateCounter and use a using directive since a PerformanceCounter is IDisposable. Like this:

using (var counter = CreateCounter())
{
     // Do some work
}

Then the counter will always be cleaned up, even if you throw during the test.

Otherwise, I think what you want is to create a new thread. You can then you thread.Join() to wait for the thread to complete. See the System.Threading namespace for more info.

0

精彩评论

暂无评论...
验证码 换一张
取 消