开发者

Making WPF application multiprocess

I currently have a multithreaded application which runs in following order:

  1. Start up and change XML file
  2. Do work
  3. Change XML to default values
开发者_运维技巧

The step 3 is very important and I have to insure that it always happens. But if the application crashes, I might end up with the wrong XML.

The scenario where I am using it is:

My application is a small utility which connects to a remote device, but on the same machine there is a running service which is connected to the same remote device, which I want to connect to. Service exposes restartService method and during startup depending on the XML data it will connect to the remote device or will not. So in the end I have to ensure that whatever happened to my application, XML is set to the default state.

I thought having a thread running as a separate process and checking every n seconds if the main process is alive and responding would solve this issue. But I have found very few examples of multiprocess applications in C#. So if someone could show an example of how you to create a thread which runs as a separate process, that would be great.

What if I create a separate project - console application. It is compiled into separate executable and is launched from within main application. Then use IpcChannel for the communication between 2 processes. Or Create a WCF application. Will one of these approach work?


A Thread belongs to a Process, so if the process dies then so do all it's threads. Each application is expected to be a single process and while you can launch additional processes it sounds like a complex solution to what might be a simple problem.

Rather than changing and reverting the file could you just read it into memory and leave the filesystem alone?


You can subscribe to an event called DispatcherUnhandledException so when ever an Unhandled exception is thrown , you can safely revert your XML settings.

 public partial class App : Application
{
    public App()
    {
        this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
    }

    void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        //When ever an Unhandeled exception is thrown

        // You can change your XML files to default values.
    }

}

// If you killed process through Task Manager

AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);

void CurrentDomain_ProcessExit(object sender, EventArgs e)
    {
        // Change your Settings Here.
    }

// If you initiated Windows ShutDown

this.SessionEnding += new SessionEndingCancelEventHandler(App_SessionEnding);

  void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
    {
        // XML Changes
    }


What you are talking about is usually called "supervision" in mainframe computing and other large-ish computing infrastructures. A supervised process is a process that runs under the scrutiny of a supervisor process, which restarts it or otherwise "fixes" the problem if the former crashes or is unable to finish its job.

You can see a glimpse of this in the way that Windows restarts services automatically if they stop working; that is a very simplistic version of a supervision subsystem.

As far as I understand, this is a complex area of computer engineering, and I don't think that Windows or .NET provide a programmatic interface to it. Depending on your specific needs, you might be able to develop a simple approach to it.


Consider setting a "dirty" flag in your config file and storing a backup of the default XML in another file. When your application starts it changes the XML and sets the flag. If it successfully completes then it resets the flag and restores the XML. Your service checks the flag to see if it needs to use the last XML written by your app or switch to the backup file.


I think that whether the application is multithreaded or multiprocess or whatever is not actually the problem you need to solve. The real problem is: how do I make this operation atomic?

When you say that you have to insure that step 3 always happens, what you're really saying is your program needs to perform an atomic transaction: either all of it happens, or none of it happens.

To accomplish this, your process should be designed the way that database transactions are designed. It should begin the transaction, do the work, and then either commit the transaction or roll it back. The process should be designed so that if, when it starts up, it detects that a transaction was begun and not committed or rolled back by an earlier run, it should start by rolling back that transaction.

Crucially, the commit method should have as little instability as possible. For instance, a typical way to design a transactional process is to use the file system: create a temporary file to indicate that the transaction has begun, write the output to temporary files, and then have the commit method rename the temporary files to their final names and delete the transaction-flag file. There's still a risk that the file system will go down in between the time you've renamed the files and the time you've deleted the flag file (and there are ways to mitigate that risk too), but it's a much smaller risk than the kind you've been describing.

If you design the process so that it implements the transactional model, whether it uses multiprocessing or multithreading or single-threading is just an implementation detail.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜