I have an application that imports data read from text files from a directory into a database. I have a UI that allows the user to click an import button and begin importing data and when the user clicks on that button again I wanted to stop importing the data in those files. I began using threads to allow this, so that I would not freeze up the UI while data was being imported. But Im having a few issues. I started using thread.Abort() to kill the thread after the user stops wanting to import but when the user clicks import again, some duplicate data is added to the database because it begins reading at the top of the text file which I dont want. I have been told to use ManualResetEvents and Thread.Join() to trigger for the import to finish, but im confused how that is supposed to work. Right now my code looks like this:
public ManualResetEvent event1 = new ManualResetEvent(false);
public Thread workerThread;
public Form1
{
InitializeComponent();
}
private void importButton_Click(object sender, EventArgs e)
{
if(importButton.Text == "Begin Import")
{
importButton.Text = "Stop Import";
//runs a service that begins reading and importing data and writing to
//a "console" box.
Service service = new Service(consoleBox);
//run the new thread to begin importing data
workerThread = new Thread(service.importData);
workerThread.Start();
}
else
{
importButton.Text = "Begin Import";
event1.Set();
while(!event1.WaitOne(TimeSpan.FromSeconds(4)))
{ //imports data for 30 more text files
service.importData(30);
workerThread.Join();
}
}
}
Basically what im trying to do is to keep the tread looping and checking to see if there is any files to be read, if there is then import The Data otherwise sleep for 4 seconds. Should I be using a threading Timer for this? I am a bit unsure of what to do.
Do not, in any way, block the UI thread by calling
Thread.JoinorManualResetEvent.WaitOne. This will do exactly what you were trying to prevent; freeze the UI. Instead you need to create the MRE with its state initially set totrue. Then in theimportDatamethod you need to periodically callWaitOneto see if importing should proceed (when the event is signaled) or pause (when the event is unsignaled).Here is a rough sketch of how you would call
WaitOneinside theimportDatamethod. Obviously, you would need to make adjustments to fit it into your specific implementation.Then from your
importButton.Clickevent handler you can callevent1.Resetto pause the import operation orevent1.Setto resume it.Also, you should try to avoid calling
Thread.Abortat all costs. It usually leads to more problems unless extra-special-nearly-impossible care is taken to avoid corrupting the state of the AppDomain.