I am pretty new to C#, but I do have some experience with programming ("some" being the operative word here). I am wondering what is the best way to completely exit out of code at a certain time.

For example, I am writing an application to read in a Photoshop file, measure all the slices, then generate some HTML based on that information.

Right now, I have a class (PSDFile) that performs the necessary operations to read the PSD file and gather the slice information. This information is held in another class (Slices). Once that data is gathered, it is passed into another class (HTMLGen) that performs the necessary operations to turn the Slice information into HTML.

The problem I'm running into is when I'm checking each stage for errors. In the PSDFile class, I check to make sure that the file exists first. If not, I need to alert the user via message box and stop the process. If so, I proceed to the next step, measuring the slices. If there is an error with the slices, I need to again alert the user via message box and stop the process. There are other places in the code where I need to check for certain things and stop if the criteria is not right.

What is the best way to go about doing this? Right now I could do a bunch of if/then statements with "return", but as the application gets large (I plan on adding a lot more features to this), I think doing it that way would be bad.

Can anyone point me in the right direction? Hope this makes sense.

Recommended Answers

All 9 Replies

If you want to exit out of code completely call Application.Exit() . Is this what you were referring to?

If you want to exit out of code completely call Application.Exit() . Is this what you were referring to?

I don't know, but I'll give that shot. Wouldn't that completely shut down the application? Also, what if the code is part of a Class Library that has no need for the System.Windows.Forms namespace (which I believe Application is a part of).

Ah. In this case you would probably want to raise an event on your worker classes that fired off on the executing application to prompt the user. You don't want to bury messagebox code inside of a DLL. Would this be an acceptable solution?

Ah. In this case you would probably want to raise an event on your worker classes that fired off on the executing application to prompt the user. You don't want to bury messagebox code inside of a DLL. Would this be an acceptable solution?

That sounds a lot more like what I am looking for. How should I go about doing this? For example, not all message boxes would just be "OK". Some might be Yes,No,Cancel. In the event that the result is Cancel, I want to stop the code from running (but not the application).

Here, I framed up an example of how to do it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace daniweb.pds
{
  public class PSDFile
  {
    private string _fileName;

    public string FileName
    {
      get { return _fileName; }
    }

    /// <summary>
    /// Occurs when a converted PSD file is about to be saved with a new extension
    /// and the destination file exists
    /// </summary>
    public event OnDestinationFileExists OnDestinationFileExists;

    public PSDFile()
    {
    }
    public PSDFile(string FileName)
      : this()
    {
      this._fileName = FileName;
    }

    public void DoWork()
    {
      System.Threading.Thread.Sleep(500); //simulate busy work!
      //Now its time to save the file
      string outFile = Path.ChangeExtension(this.FileName, ".jpg");
      if (File.Exists(outFile) && !RaiseDestinationFileExists(outFile))
      {
        return; //Stop processing, they pressed cancel!
      }

      File.Delete(outFile);
      File.WriteAllBytes(outFile, Guid.NewGuid().ToByteArray()); //sample file
    }

    /// <summary>
    /// Raises the destination file exists method
    /// </summary>
    /// <returns>True if the operation should continue, False to abort</returns>
    private bool RaiseDestinationFileExists(string fileName)
    {
      OnDestinationFileExists temp = this.OnDestinationFileExists;
      if (temp != null)
      {
        DestinationFileExistsArgs args = new DestinationFileExistsArgs(fileName);
        temp(this, args);
        return !args.Cancel;
      }
      else
        return true; //This is the default value if nobody subscribes to the event
    }
  }

  #region delegates and event args
  public delegate void OnDestinationFileExists(object sender, DestinationFileExistsArgs e);
  public class DestinationFileExistsArgs : EventArgs
  {
    private string _fileName;
    private bool _cancel;

    public string FileName
    {
      get { return _fileName; }
    }
    public bool Cancel
    {
      get { return _cancel; }
      set { _cancel = value; }
    }
    
    protected DestinationFileExistsArgs()
    {
      this.Cancel = false;
    }
    public DestinationFileExistsArgs(string FileName)
      : this()
    {
      this._fileName = FileName;
    }
  }

  //This is a sample of inheriting for your next event
  public delegate void OnSliceError(object sender, DestinationFileExistsArgs e);
  public sealed class SliceErrorArgs : DestinationFileExistsArgs
  {
    private int _sliceNumber; //I guess a slice is numeric?
    public int SliceNumber
    {
      get { return _sliceNumber; }
    }
    private SliceErrorArgs()
      : base()
    {
    }
    public SliceErrorArgs(string FileName, int SliceNumber)
      : base(FileName)
    {
      this._sliceNumber = SliceNumber;
    }
  }
  #endregion
}

And calling it:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace daniweb.pds
{
  public partial class frmPsd : Form
  {
    public frmPsd()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      PSDFile file = new PSDFile(@"C:\photo1.txt");
      file.OnDestinationFileExists += new OnDestinationFileExists(file_OnDestinationFileExists);
      file.DoWork();
    }

    void file_OnDestinationFileExists(object sender, DestinationFileExistsArgs e)
    {

      if (MessageBox.Show(
        string.Format("The destination file '{0}' exists." + Environment.NewLine +
        "Press 'YES' to cancel the operation, press 'NO' to overwrite the file", e.FileName), this.Text,
        MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
      {
        e.Cancel = true;
      }
    }
  }
}

Run that code and the first time it will run OK since the file doesn't exist. The second time it will prompt the user, and you can abort the operation.

Wow, very nice! I'm going to look over this and try and understand it. Thank you so much!

You're welcome

Let me know if you have any questions and don't forget to mark the thread as solved if this gives you the desired functionality ;)

Good luck!

You're welcome

Let me know if you have any questions and don't forget to mark the thread as solved if this gives you the desired functionality ;)

Good luck!

Thanks again for the code. I think I pretty much understand what you are doing with it. One question though, would it be wise of me to start a Thread? I'm thinking about this because I will be passing control of the program around from various object to various object (possibly several different DLLs). Maybe I could create one DLL that handles only the Message Boxes and termination of threads. I also think I may need to go this route because there are several places in the main executable and in user controls that I want to use things like Progress Bars.

Your thoughts?

I'm not sure you have provided enough information about your assemblies and what they do for me to really give you an answer on that. But more than likely if you're doing _any_ sort of image processing you want to create another thread because it will always be a little on the slow side. I don't see the benefit in having a DLL that handles the message boxes because message boxes should only be used in the presentation layer, ie from a windows form application. There are exceptions but they are few and far between (such as creating a wizard screen, where you need to prompt) the user. But if you force message boxes in your assembly you're taking away the ability to automate what your code does.

Describe your application a little deeper and we'll go from there.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.