none
Stop a multiple file save operation RRS feed

  • Question

  • Hi,

    I made an export function to save files from a Oracle table. I want to be able to stop the file save function with "ESC". How to make that? I think i have to use threads but i do not know where to start.

    my export function (first raw version) :

    private void ButtonExportImages_Click(object sender, EventArgs e)
            {
                Cursor.Current = Cursors.WaitCursor;
                ToolStripStatusLabel1.Text = "Foto bestanden worden geëxporteerd...";
                this.Refresh();
    
                OracleCommand _oraComm = new OracleCommand();
    
                OracleDataReader _dr = null;
                _oraComm.Connection = _oraConn;
                _oraComm.CommandType = CommandType.Text;
    
                _oraComm.CommandText = TextBoxQueryText.Text;
                _dr = _oraComm.ExecuteReader();
    
                string targetFolder = TextBoxImageExportLocation.Text;
                try
                {
                    int counter = 0;
                    while (_dr.Read())
                    {
                        string targetFile = Path.Combine(targetFolder, _dr["FILENAME"].ToString());
    
                        if (File.Exists(targetFile))
                         {
                            Logging.WriteToLogInformation("Bestandsnaam komt reeds voor en is niet geëxporteerd : " + targetFile);
                            counter++;
                            continue;
                         }
    
                        using (var fs = new FileStream(targetFile, FileMode.Create))
                        {
                            byte[] filedata = (byte[])_dr["IMAGE"];
                            fs.Write(filedata, 0, filedata.Length);
                        }
                    }
                    Cursor.Current = Cursors.Default;
                    ToolStripStatusLabel1.Text = string.Empty;
                    if (counter >=1 )
                    {
                        MessageBox.Show("Dubbele besstandsnamen aangetroffen." + Environment.NewLine +
                        Environment.NewLine +
                        "Kijk in het log bestand welke bestanden niet zijn geëxporteerd.",
                        "Waarschuwing",
                        MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }
                catch (OracleException ex)
                {
                    Logging.WriteToLogError("Onverwachte fout opgetreden bij het lezen van de Oracle tabel.");
                    Logging.WriteToLogError("Melding:");
                    Logging.WriteToLogError(ex.Message);
                    if (this.DebugMode) { Logging.WriteToLogDebug(ex.ToString());  }
    
                    MessageBox.Show("Onverwachte fout opgetreden bij het lezen van de Oracle tabel." + Environment.NewLine +
                        Environment.NewLine +
                        "Kijk in het log bestand voor de foutmelding.",
                        "Fout",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
    
                }
                catch (Exception ex)
                {
                    Logging.WriteToLogError("Onverwachte fout opgetreden bij opslaan van de fotobestanden.");
                    Logging.WriteToLogError("Melding:");
                    Logging.WriteToLogError(ex.Message);
                    if (this.DebugMode) { Logging.WriteToLogDebug(ex.ToString()); }
                    MessageBox.Show("Onverwachte fout opgetreden bij opslaan van de fotobestanden.." + Environment.NewLine +
                        Environment.NewLine +
                        "Kijk in het log bestand voor de foutmelding.",
                        "Fout",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                } 
                finally
                {
                    _oraComm.Dispose();
                }
            }


    • Edited by HansvB69 Friday, June 7, 2019 6:17 PM
    Friday, June 7, 2019 6:17 PM

All replies

  • Hello,

    Here is a pattern to try out. In the Task.Delay(500) is a 1/2 second, you can lower this is so desired. And rather than having the while loop check for a condition place the condition in an if statement in the loop for the data reader. I didn't have time to setup a full fledge code sample reading data so I simply did the while.

    using System;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1
    {
        public partial class Form1 : Form
        {
            private bool _currentlyRunning;
            public Form1()
            {
                InitializeComponent();
            }
            protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
            {
                if (keyData != (Keys.Escape)) return base.ProcessCmdKey(ref msg, keyData);
                _currentlyRunning = false;
                return true;
    
            }
    
            private async void button1_Click(object sender, EventArgs e)
            {
                _currentlyRunning = true;
    
                while (_currentlyRunning)
                {
                    await Task.Delay(500);
                    Console.WriteLine("Currently running");
                }
    
                Console.WriteLine(_currentlyRunning);
            }
        }
    }
    


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Friday, June 7, 2019 7:24 PM
    Moderator
  • Hi,

    Thanks. where do i start my lomg running function?

    Saturday, June 8, 2019 8:26 AM
  • Hi 

    Thanks for the feedback.

    >>where do i start my lomg running function?

    I am not sure what you mean. Could you describe it clearly?

    We are waiting for your update.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 10, 2019 9:36 AM
    Moderator
  • Your whole ButtonExportImages_Click is your long running function.  Everything starting with the statement where you create the OracleCommand can be spun off into a separate thread.

    As a side note, calling "this.Refresh();" inside your button click handler isn't very useful.  All that does is mark that the window needs to be repainted.  It won't actually BE repainted until the click handler returns and the app can get back to check for more messages.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Monday, June 10, 2019 6:35 PM
  • Hi,

    Thanks. where do i start my lomg running function?

    Take the code currently in the button click event, place it into a method, as per below, PerformSomeLongRunningProcess() would be your click code.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Monday, June 10, 2019 6:56 PM
    Moderator
  • Sorry, I really don't get this. ik think i have to google some more.

    Friday, June 21, 2019 5:21 PM
  • Don't feel too badly.  It takes some time to "get" the concept of multithreading.

    Let me propose a metaphor.  Let's say you are a barber, cutting a customer's hair, and the phone rings.  You could stop, put the scissors down, and go answer the phone, but while you're doing that, your customer isn't being served.  He's "blocked".

    Now, instead, let's you had your assistant Bill sitting by.  When the phone rings, you say to Bill, "hey Bill, go answer the phone".  Bill is using the same shop and the same resources as you, but your customer continues to get service while the phone call is dealt with.

    In the case of your app, the customer is the window event handler.  You the barber are the "main thread".  It's your job to handle window events, you are the only one that can handle them, and if you are busy, events don't get handled.

    Bill, in my example, is a long-running task you need to have handled.  You want to get it done without interfering with your primary customer.  Thus, you start a thread.  Since you are sharing the same resources, you can communicate by setting variables or firing events, and other than that, both threads continue to operate in the same program space.

    The key is to figure out what part of the code can really run independently.  Make that the thread function.  Then figure out what communication needs to happen.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.


    Friday, June 21, 2019 6:28 PM