access all ListView Items from Task.Run() gives this error InvalidOperationException: 'Cross-thread operation not valid

In my code I am using await Task.Run so the form does not freeze while uploading files to SFTP

I got similar error when I was trying to write to textbox and fixed it with LogUpload function

but now I get this error when I try to access ListView items

System.InvalidOperationException: 'Cross-thread operation not valid: Control 'lvwFiles' accessed from a thread other than the thread it was created on.'

I wonder how can I fix that

here is my code

 await Task.Run(() =>
            {
                using (SftpClient client = new SftpClient(host, port, username, password))
            {
                client.Connect();
                if (client.IsConnected)
                {
                    LogUpload("I'm connected to the client" + "\r\n");
                    foreach (ListViewItem item in lvwFiles.Items)   //<<---- Causing the error
                    {
                        string fileName = item.SubItems[0].Text;
                        string uploadFile = item.SubItems[1].Text;

and the function to LogUpload is

    private void LogUpload(string txt)
    {
        if (txtLog.InvokeRequired)
        {
            txtLog.Invoke(new MethodInvoker(delegate { txtLog.Text = txt + txtLog.Text; }));
        }
    }

Solution 1:

The error is occurring because you are trying to read the items from the ListView from within the Task, which is running on another thread. Instead of reading the items within the Task.Run call, copy them into an array on the line above Task.Run and reference that array instead.

The CopyTo method provides an easy way to copy the ListViewItems to an array. It would look something like this:

// instantiate new array to hold copy of items
var copyOfItems = new  ListViewItems[lvwFiles.Items.Count];
// copy items
lvwFiles.Items.CopyTo(copyOfItems, 0);

Now just reference copyOfItems within your Task!