Actuellement, j'ai quelque chose comme:classe OpenNETCF FTP question multithreading
public partial class Form1 : Form
{
delegate void StringDelegate(string value);
private FTP m_ftp;
public Form1()
{
InitializeComponent();
}
private void connect_Click(object sender, EventArgs e)
{
OnResponse("Connecting");
m_ftp = new FTP(server.Text);
m_ftp.ResponseReceived += new FTPResponseHandler(m_ftp_ResponseReceived);
m_ftp.Connected += new FTPConnectedHandler(m_ftp_Connected);
m_ftp.BeginConnect(user.Text, password.Text);
}
void m_ftp_Connected(FTP source)
{
// when this happens we're ready to send command
OnResponse("Connected.");
}
void m_ftp_ResponseReceived(FTP source, FTPResponse Response)
{
OnResponse(Response.Text);
}
private void OnResponse(string response)
{
if (this.InvokeRequired)
{
this.Invoke(new StringDelegate(OnResponse), new object[] { response });
return;
}
}
private void getFileList_Click(object sender, EventArgs e)
{
FTPFiles files = m_ftp.EnumFiles();
fileList.Items.Clear();
foreach (FTPFile file in files)
{
fileList.Items.Add(new ListViewItem(new string[] { file.Name, file.Size.ToString() }));
}
tabs.SelectedIndex = 1;
}
private void upload_Click(object sender, EventArgs e)
{
FileStream stream = File.OpenRead("\\My Documents\\My Pictures\\Waterfall.jpg");
m_ftp.SendFile(stream, "waterfall.jpg");
stream.Close();
}
Ce qui fonctionne très bien - cet exemple a été prise à partir des échantillons. Cependant, après une récente visite, j'ai une question. Dans ce cas particulier, puisque la fonction OnResponse() ne met pas à jour l'interface utilisateur, elle ne semble pas utile ici. Je l'ai supprimé (ainsi que tous les appels à celui-ci) et il fonctionne toujours comme avant. Est-ce que je manque quelque chose? Après avoir lu plus sur le multi thread avec des formulaires, j'ai fini par comprendre que ce mécanisme (démontré dans le code ci-dessus) est là pour s'assurer que l'interface utilisateur est réactive.
Donc, dans le cas où nous devons dire, mettre à jour un élément d'interface utilisateur (comme zone de texte, l'étiquette, etc.), nous aurions OnResponse mis en œuvre comme suit:
delegate void StringDelegate(string dummy);
void OnResponse(string dummy)
{
if(!InvokeRequired)
{
button1.Text = dummy;
}
else
Invoke(new StringDelegate(OnResponse),new object[] {enabled});
}
Si cette fonction est implémentée comme:
delegate void StringDelegate(string dummy);
void OnResponse(string dummy)
{
if(InvokeRequired)
{
Invoke(new StringDelegate(OnResponse),new object[] {dummy});
return;
}
}
Quelle est l'utilité de l'avoir? Est-ce absolument nécessaire?
Et une autre question: l'objet ftp s'exécute-t-il sur son propre thread ici?
Merci! sorta fait. Le code actuel peut mettre à jour l'interface utilisateur à l'intérieur de m_ftp_ResponseReceived() ... C'est pourquoi je suis confus. Ma compréhension était que l'objet FTP était en cours d'exécution dans son propre fil, mais je ne devrais pas être en mesure de mettre à jour l'interface utilisateur dans m_ftp_ResponseReceived() sauf si j'utilise Invoke. Ce qui donne? Je voudrais continuer à utiliser le BeginConnect() car je veux que l'interface utilisateur soit réactive. – sarsnake
également s'il vous plaît noter que OpenNetCF n'a pas de méthode Connect dans la classe FTP, seulement BeginConnect() – sarsnake
Je viens de le tester plus, et il semble que je suis capable de mettre à jour l'interface utilisateur de m_ftp_ResponseReceived(). mais IMPOSSIBLE de le faire depuis m_ftp_Connected(). Toute une observation intéressante. m_ftp_Connected doit être exécuté sur le thread de l'interface utilisateur. – sarsnake