Je cherche à uploader des données sur un serveur ftp et je rencontre plusieurs problèmes dont je ne connais pas la source.
- Tout d'abord, à certains moments pour un upload long (durée : >1h, taille : >50 Mo) j'ai une exception interrompant mon transfert me disant que la connexion a été fermée (SocketException). Quelle en est la cause ?
- Ensuite, j'ai remarqué quelque chose qui ressemble à un dead lock : quand une exception survient, avec mes habitudes d'être propres je tente de fermer le flux renvoyé par ftp_command.GetRequestStream() (simplement en appelant Close ou via une directive using(stream)) et alors soit le programme se plante sur l'accolade fermante du using, soit il se plante sur le Close quand je l'utilise et là, rien à faire, Thread.Abort ne fonctionne pas pour kicker le thread, VS ne peut plus rien faire, il me dit juste qu'une frame native est au dessus et franchement impossible de faire quoique ce soit du thread qui contient ce code. Y aurai t il une possibilité de deadlock avec FtpWebRequest ?

Si nécéssaire, mon code d'upload :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 
private void PublishSetupInternal_FTPUploadFile(string ftp_file, string local_file, NetworkCredential credential, CancelEventHandler cancelHandler, ProgressHandler progressHandler)
        {
            var cancel_arg = new CancelEventArgs(false);
 
            FtpWebRequest ftp_command = (FtpWebRequest)FtpWebRequest.Create(ftp_file);
            ftp_command.Credentials = credential;
            ftp_command.Method = WebRequestMethods.Ftp.UploadFile;
            FTPUtils_InitStandardCommand(ftp_command);
 
            byte[] copy_buffer = new byte[1 * 1024]; //1 ko ... de toute façon vu que c'est internet ça ira pas très vite.
            int rd = 0;
            long total_read = 0;
            try
            {
                DateTime startTime = DateTime.Now;
                int timeLeft = 0;
                double timepercent = 0;
                TimeSpan timeelapsed;
 
                using (FileStream fi = new FileStream(local_file, FileMode.Open, FileAccess.Read))
                {
                    ftp_command.ContentLength = fi.Length;
 
                    Stream r_stream = ftp_command.GetRequestStream();
                    try
                    {
                        bool cancel = false;
                        bool finished = false;
 
                        Exception delay_ex = null;
 
                        Thread temp_th = new Thread(new ThreadStart(delegate
                            {
                                try
                                {
                                    while (total_read < ftp_command.ContentLength && !cancel)
                                    {
                                        rd = fi.Read(copy_buffer, 0, copy_buffer.Length);
 
                                        if (rd == 0)
                                            throw new InvalidOperationException("Lecture à partir du fichier local échouée");
                                        else
                                        {
                                            total_read += rd;
                                            r_stream.Write(copy_buffer, 0, rd);
                                        }
                                    }
                                    finished = true;
                                }
                                catch (Exception ex)
                                {
                                    finished = true;
                                    delay_ex = ex;
                                }
                            }));
                        temp_th.Name = "Uploading File Thread";
                        temp_th.IsBackground = true;
                        temp_th.Start();
 
                        while (!finished)
                        {
                            if (cancelHandler != null)
                            {
                                cancelHandler.Invoke(this, cancel_arg);
 
                                if (cancel_arg.Cancel)
                                {cancel = true;
                                    return;
                                }
                            }
 
                            if (progressHandler != null)
                            {
                                timeLeft = 0;
                                if (ftp_command.ContentLength > 0 && timepercent > 0)
                                {
                                    timepercent = ((double)total_read) / ((double)ftp_command.ContentLength);
                                    timeelapsed = DateTime.Now.Subtract(startTime);
                                    timeLeft = (int)((double)timeelapsed.TotalMilliseconds / (double)timepercent - timeelapsed.TotalMilliseconds);
                                }
                                progressHandler.Invoke(total_read, ftp_command.ContentLength, timeLeft);
                            }
 
                            Thread.Sleep(10);
                        }
 
                        if (delay_ex != null && total_read != fi.Length)
                        {
                            Trace.WriteLine(delay_ex.ToString());
                            throw new WebException(delay_ex.Message, delay_ex);
                        }
                    }
                    finally
                    {
                        try
                        {
                                r_stream.Close();
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine(ex.ToString());
                            MessageBox.Show(ex.ToString(), "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
 
                }
            }
            finally
            {
                ftp_command.GetResponse().Close();
            }
        }
 
private void FTPUtils_InitStandardCommand(FtpWebRequest ftp_command)
        {
            ftp_command.UseBinary = true;
            ftp_command.UsePassive = PublicationProperties.UsePassiveMode;
            ftp_command.Timeout = Timeout.Infinite; /* temps infini pour l'opération */
            ftp_command.ReadWriteTimeout = 5 * 60 * 1000; /* 5 mn pour la lecture/écriture */
        }

Merci d'avance si quelqu'un me répond ...