Click here to Skip to main content
15,888,461 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
C#
private void button2_Click(object sender, EventArgs e)
       {
           searchpattern = txtpatterns.Lines;
           searchpattern = searchpattern.Take(searchpattern.Count() - 1).ToArray();
           sourcepath = txtsourcepath.Text;
           destinationpath = txtUnzippath.Text;
           BuildingNames = txtbuildings.Lines;
           BuildingNames = BuildingNames.Take(BuildingNames.Count() - 1).ToArray();
           #region Validating Required Fields
           if (txtsourcepath.TextLength == 0)
           {
               MessageBox.Show("Please Enter the Search Directory path");
           }
           else if (txtpatterns.TextLength == 0)
           {
               MessageBox.Show("Please Enter the Start Date and End date to start the process");
           }
           else if (txtUnzippath.TextLength == 0)
           {
               MessageBox.Show("Please Enter the path to unzip the File");
           }
           else if (txtbuildings.TextLength == 0)
           {
               MessageBox.Show("Please Select the buildings from the list");
           }
           #endregion
           else
           {
               //SQL_Bulk_Copy oHelper = new SQL_Bulk_Copy();
               //string logFilePath = @"C:\Users\jqy9jzy\Desktop\Testing\SVRP0008C8B9\SVRP0008C8B9Unzip\DataFeed_20180419_6276.log";
               //oHelper.BulkInsertIntoDatabase(logFilePath);
               Task task = new Task(Callmethod);
               task.Start();
               task.Wait();
           }
       }

       public async void Callmethod()
       {
           Hide();

           foreach (var pattern in searchpattern)
           {
               var txtFiles = Directory.EnumerateFiles(sourcepath, pattern, SearchOption.AllDirectories);
               foreach (string filepath in txtFiles)
               {
                   zipfilepath.Add(filepath);
               }
           }
           Task<int> task = ReadFile.FILE_C(zipfilepath);
           int count = await task;
           if (count == zipfilepath.Count)
           {
               Directory.Delete(Unzip.destinationpath, true);
               bool directoryExists = Directory.Exists(Unzip.destinationpath);
               Close();
           }
       }



ReadFile code :
public class ReadFile
   {
       protected internal static async Task<int> FILE_C(List<string> zipfilepath)
       {
           int count = 0;

           try
           {
               if (!Directory.Exists(Unzip.destinationpath))
               {
                   Directory.CreateDirectory(Unzip.destinationpath);
               }

               foreach (string filepath in zipfilepath)
               {
                   await Task.Run(()=> Unzip.data(filepath));
                   count += 1;
               }
           }
           catch (Exception ex)
           {
               throw ex;
           }
           return count;
       }
   }


What I have tried:

I have list of Zipfilepath, I'm creating a directory and unzip them and load into sql.

This is the actual process of my application.

I want to do this asynchronously because I have like 1500 files in that list.

It has to unzip, read and load the file to sql async,Which has await until it completes the loop, after completing the loop the application has to close automatically.

When I tries to work with the above code, I'm getting the following error.
ERROR: "cross-thread operation not valid: control 'Form1' accessed from a thread other than the thread it was created on." + c# + winform"


Thank in advance, any help is appreciated.
Posted
Updated 31-May-18 9:36am
v2
Comments
[no name] 31-May-18 17:25pm    
I don't see any point in running this async.

It's not like you have 1500 "channels".

Give the "whole thing" to a background worker and get on with other stuff.

1 solution

Make it async all the way down:
C#
private async void button2_Click(object sender, EventArgs e)
{
    ...
    else
    {
        await Callmethod();
    }
}

private async Task Callmethod()
{
    Hide();
    
    List<string> filesToZip = searchpattern
        .AsParallel()
        .SelectMany(pattern => Directory.EnumerateFiles(sourcepath, pattern, SearchOption.AllDirectories))
        .ToList()
    ;
    
    int count = await ReadFile.FILE_C(filesToZip);
    if (count == filesToZip.Count)
    {
        Directory.Delete(Unzip.destinationpath, true);
        bool directoryExists = Directory.Exists(Unzip.destinationpath);
        Close();
    }
}

public class ReadFile
{
    protected internal static async Task<int> FILE_C(IEnumerable<string> zipfilepath)
    {
        int count = 0;
        
        if (!Directory.Exists(Unzip.destinationpath))
        {
            Directory.CreateDirectory(Unzip.destinationpath);
        }

        foreach (string filepath in zipfilepath)
        {
            await Task.Run(()=> Unzip.data(filepath)).ConfigureAwait(false);
            count += 1;
        }
        
        return count;
    }
}

NB: If you really need to re-throw an exception, use throw;, not throw ex; - the latter destroys the stack trace.

However, in this instance, since all you're doing is re-throwing the exception, there's no point in catching it in the first place.
 
Share this answer
 
v2
Comments
Member 13801408 31-May-18 16:30pm    
Hi Richard,
Thanks for the help.

When I tried running this, I'm getting correct output what I was expecting. But the foreach loop is iterating synchronously. But I want It to run in Asynchronously. So that I can improve the performance.

Thanks, in advance.

This is the unzip code:

protected internal static void data(string filepath)
{
try
{
//Extract Sub-Directory from the filepath
Create_Sub_DirectoryUnzip = filepath .Substring(MainForm.sourcepath.Length+1);
Create_Sub_DirectoryUnzip = Path.GetDirectoryName(Create_Sub_DirectoryUnzip);
//Log Filename without extension
Log_Filename = Path.GetFileNameWithoutExtension(filepath);
Log_Filename = Log_Filename.Remove(Log_Filename.Length - 4);
//Extract path to unzip the file
Extract_Path = destinationpath + "\\" + Create_Sub_DirectoryUnzip + "Unzip" ;
Unzipfilepath = Extract_Path + "\\" + Log_Filename + ".log";

if (!File.Exists(Unzipfilepath))
{
if (!Directory.Exists(Extract_Path))
{
Directory.CreateDirectory(Extract_Path);
}
ZipFile.ExtractToDirectory(filepath, Extract_Path);
}

if (new FileInfo(Unzipfilepath).Length > 0)
{
var contentvalid = File.ReadLines(Unzipfilepath).Skip(0).Take(1).First();
var content = File.ReadLines(Unzipfilepath).Skip(1).Take(1).First();

string valid = contentvalid.Split('|').Skip(0).Take(1).First();
if (valid == "Timestamp")
{
string RecordType = content.Split('|').Skip(7).Take(1).First();
if (RecordType == "10")
{
SQL_Bulk_Copy oHelper = new SQL_Bulk_Copy();
logFilePath = Unzipfilepath;
oHelper.BulkInsertIntoDatabase(logFilePath);
}
else
{
File.Delete(Unzipfilepath);
}
}
else
{
File.Delete(Unzipfilepath);
}
}
else
{
File.Delete(Unzipfilepath);
}
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
Richard Deeming 31-May-18 16:39pm    
Which foreach loop?

I've updated the answer so that the directory searching should happen in parallel.

I don't think you could get the unzip code to run in parallel as it stands, since it seems to rely on shared state.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900