跨线程操作无效:控制'form1'从其创建的线程以外的线程访问。“ + C#+ winform [英] Cross-thread operation not valid: control 'form1' accessed from a thread other than the thread it was created on." + C# + winform

查看:114
本文介绍了跨线程操作无效:控制'form1'从其创建的线程以外的线程访问。“ + C#+ winform的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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:




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;
       }
   }





我尝试了什么:



我有Zipfilepath列表,我正在创建一个目录并解压缩并加载到sql中。



这是我申请的实际过程。



我想异步这样做,因为我在该列表中有1500个文件。



它必须将文件解压缩,读取并加载到sql async,它等待完成循环,完成循环后应用程序必须自动关闭。



当我尝试使用上面的代码时,我收到以下错误。

错误:跨线程操作无效:控制'Form1'从一个线程,而不是它创建的线程。 + c#+ winform





提前感谢,感谢任何帮助。



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.

推荐答案

让它 async 一直向下:

Make it async all the way down:
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;
    }
}



注意:如果真的需要重新投掷异常,使用 throw; ,而不是抛出ex; - 后者破坏堆栈跟踪。



但是,在这种情况下,由于您所做的只是重新抛出异常,因此首先捕获它是没有意义的。


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.


这篇关于跨线程操作无效:控制'form1'从其创建的线程以外的线程访问。“ + C#+ winform的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆