How can I handle an IOException which I know can never be thrown, in a safe and readable manner?

后端 未结 8 1839
生来不讨喜
生来不讨喜 2021-02-02 12:07

\"The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong go

8条回答
  •  无人及你
    2021-02-02 13:13

    I have experienced the same problem.

    In the simplest case you inform the user of the error and suggest to either to repeat or to cancel the operation.

    In general case, workflow is a sequence of actions (I/O including), where each action "assumes" that the previous one had succeeded.

    The approach I have chosen is to create a list of 'roll-back' actions. If the workflow succeeds, they are ignored. If an exception occurs, I execute rollbacks and present an exception to the user.

    This:

    • keeps integrity of data
    • allows to code much easier

    Typical function is like:

    returntype func(blah-blah-blah, Transaction tr)
    {
        // IO example
        Stream s = null;
        try
        {
            s = new FileStream(filename);
            tr.AddRollback(File.Delete(filename));
        }
        finally
        {
            if (s != null)
                s.close();
        }
    }
    

    Typical usage is:

    Transaction tr = new Transaction();
    try
    {
        DoAction1(blah1, tr);
        DoAction2(blah2, tr);
        //...
    }
    catch (Exception ex)
    {
        tr.ExecuteRollbacks();
        // queue the exception message to the user along with a command to repeat all the actions above
    }
    

    This is a little bit trickier in real-world, because

    • sometimes it is necessary to obtain a bunch of locks before execution actions
    • rollback code should be exception-silent itself (for instance)

    But I have already get used to this approach, now my applications are more stable.

提交回复
热议问题