所以我一直在从我的主窗体调用一个类方法,并在那里启用线程。但是当我将 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 不应被阻止
听起来您已经知道从不同线程访问 UI 时必须调用
Invoke
。 TreeNode
没有 Invoke
方法,因为它们不是真正的 Control
,但它们确实有对其 TreeView
的引用,并且确实有 Invoke
方法。那么就像这样:
parentNode.TreeView.Invoke(() => {
TreeNode node = new TreeNode(directory);
parentNode.Nodes.Add(node);
});