System.InvalidOperationException:'正在从错误的线程调用对此控件执行的操作。元帅到正确的线程

问题描述 投票:0回答:1

所以我一直在从我的主窗体调用一个类方法,并在那里启用线程。但是当我将 param 传递给 obj 方法时,它显示了此错误,我无法修复它,因为 treenode 属性中没有调用方法

从 maiform 调用带有线程的方法

var PopulateTreeThread = new Thread(() =>
{
    response = treeViewObj.PopulateDirectories(rootNode, $"ftp://{hostIPAddress}:{port}",
    hostUserName, hostPassword,
    request, response);
    Thread.Sleep(25);
});
PopulateTreeThread.IsBackground = true;
PopulateTreeThread.Start();

your text

类中的方法是

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace FileManagerClient
{
    public class TreeView
    {
        public FtpWebResponse PopulateDirectories(TreeNode parentNode,
            string ftpRootPath,
            string hostUsername,
            string hostPassword,
            FtpWebRequest request,
            FtpWebResponse response
            )
        {
            try
            {
                // ftp request for each directory list
                request = (FtpWebRequest)WebRequest.Create(ftpRootPath);
                request.Credentials = new NetworkCredential(hostUsername, hostPassword);
                request.Method = WebRequestMethods.Ftp.ListDirectory;
                request.KeepAlive = true;

                response = (FtpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);

                string directoryContents = reader.ReadToEnd();
                string[] directories = directoryContents.Split(new char[] { '\r', '\n' },StringSplitOptions.RemoveEmptyEntries);

                List<string> modifiedDirectories = new List<string>();

                foreach (string directory in directories)
                {
                    // splitting directory name for refined folder
                    string[] parts = directory.Split('/');

                    // getting last string after '/' as that will be present directory "AWGSS/DG" will give DG
                    string modifiedDirectory = parts[parts.Length - 1];

                    // refined directories name to remove confusion
                    modifiedDirectories.Add(modifiedDirectory);
                }

                // converting list to string array before passing
                string[] finalDirectories = modifiedDirectories.ToArray();

                foreach (string directory in finalDirectories)
                {
                    // creating node for each directory
                    Console.WriteLine($"directory looks like this: {directory}");

                    TreeNode node = new TreeNode(directory);
                    parentNode.Nodes.Add(node);

                    Console.WriteLine($"new stream looks like this: {ftpRootPath}/{Path.GetFileName(directory)}");
                    // condition to differentiate between file and directory
                    bool isDirectory = Path.GetFileName(directory).Contains(".");

                    if (isDirectory)
                    {
                        continue;
                    }
                    else
                    {
                        // when directory found then run this method recursively
                        PopulateDirectories(node, $"{ftpRootPath}/{Path.GetFileName(directory)}", hostUsername, hostPassword, request, response);
                    }
                }
                reader.Close();

            }
            catch (WebException ex)
            {
                // Handle exception
                // MessageBox.Show($"Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                Console.WriteLine($"Error: {ex.Message}");
            }
            return response;
        }
    }
}

我试图做一个成功的多线程,它不应该阻塞 UI,但它仍然阻塞 UI 并且无法在 UI 中执行任何操作

我希望在可以使用 UI 的同时该方法正在运行,因此 UI 不应被阻止

c# .net multithreading user-interface
1个回答
0
投票

听起来您已经知道从不同线程访问 UI 时必须调用

Invoke
TreeNode
没有
Invoke
方法,因为它们不是真正的
Control
,但它们确实有对其
TreeView
的引用,并且确实有
Invoke
方法。那么就像这样:

parentNode.TreeView.Invoke(() => {
   TreeNode node = new TreeNode(directory);
   parentNode.Nodes.Add(node);
});
© www.soinside.com 2019 - 2024. All rights reserved.