IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement Windows Discussion :

Probleme thread création fichier [Débutant]


Sujet :

Développement Windows

  1. #1
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut Probleme thread création fichier
    Bonjour à tous,

    Je découvre les threads et je rencontre un problème dans le développement de mes essais. En effet, j'ai crée une class qui lorsqu'on lui fourni une liste d'adresse url pointant vers des fichiers va télécharger ceux-ci et les enregistres après avoir vérifié que le fichier n’existe pas et qui, si il existe, index le nom du fichier. Ça marche pas trop mal mais certains fichiers pose problème à l'ouverture du stream créer par File.OpenWrite (ligne 81).

    J'en déduit qu'il est utilisé par un autre thread. Je ne comprend pas pourquoi car lorsque je le crée, j'utilise un lock pour sécuriser la création du nom et du fichier. Comment puis-je corriger le problème?

    Merci de votre aide et éclaircissement.

    Ci-après le code simplifié

    Code : 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
    internal class CtrlrDownload
    {
    	private BackgroundWorker _bgWorker;
    	private ParallelOptions po = new ParallelOptions();
    	private CancellationTokenSource cts = new CancellationTokenSource();
    	object padlock = new object();
    	private int _nbATraiter = 0;
    	private int _nbTraite = 0;
    	private bool _isCanceled = false;
    	string pathWhereSave;
    	List<int> indexOk = new List<int>();
    	private int err=0;
    	ConcurrentDictionary<int, string> _errors = new ConcurrentDictionary<int, string>();
     
    	public bool HasError {  get => _errors.Count > 0; }
     
     
    	public void Run( Dictionary<int, Mark> lst, string folderPath )
    	{
    		if ( !Directory.Exists( folderPath ) )
    			Directory.CreateDirectory( folderPath );
     
    			pathWhereSave = folderPath;
     
    		if ( lst.Count == 0 )
    			return false;
     
    		cts = new CancellationTokenSource();
    		po = new ParallelOptions()
    		{
    			CancellationToken = cts.Token,
    			MaxDegreeOfParallelism = 4
    		};
     
    		_bgWorker.RunWorkerAsync( lst );
    	}
     
    	private void BgWorker_DoWork( object sender, DoWorkEventArgs e )
    	{
    		Dictionary<int, Mark> lst = e.Argument as Dictionary<int, Mark>;
     
    		try
    		{
    			Parallel.ForEach( lst, po,
    				keyValuePair => DownloadUrl( keyValuePair.Key, keyValuePair.Value )
    			);
    		}
    		catch ( OperationCanceledException ) //Cancel the parallel.foreach
    		{ }
    		catch ( Exception ex ) //other exception
    		{}
    	}
     
    	private void DownloadUrl( int index, UrlBase common )
    	{
    		try
    		{
    			DownloadFile(common.Url, common.Url.Split('/').Last(), index);
            }
    		catch (Exception ex)
    		{
    			MessageBox.Show(ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error );
    			_errors.TryAdd( index, ex.Message );
    		}
     
    		Interlocked.Increment(ref _nbTraite); //thread safe
    	}
     
    	public void DownloadFile( string url, string fileName, int index )
    	{
    		lock( padlock )
    		{
    			fileName = CreateFileName( pathWhereSave, fileName );
    			File.Create( Path.Combine(Path.Combine( pathWhereSave, fileName ) );
    		}
     
    		HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
    		HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    		long fileSize = response.ContentLength;
     
    		using ( Stream outputStream = File.OpenWrite( Path.Combine( pathWhereSave, fileName ) ) )
    		//FIXME : System.IO.IOException*: 'Le processus ne peut pas accéder au fichier 'nomfichier', car il est en cours d'utilisation par un autre processus.' 
    		using ( Stream inputStream = response.GetResponseStream() )
    		{
    			byte[] buffer = new byte[ 4096 ];
    			int bytesRead, percentComplete;
    			long totalBytesRead = 0;
    			do
    			{
    				bytesRead = inputStream.Read( buffer, 0, buffer.Length );
    				outputStream.Write( buffer, 0, bytesRead );
    				totalBytesRead += bytesRead;
    				percentComplete = (int)( totalBytesRead * 100 / fileSize );
    			} while ( bytesRead != 0 );
    		}
    	}
     
    	public static string CreateFileName( string folderPath, string fileName )
    	{
    		if ( File.Exists( Path.Combine( folderPath, fileName ) ) )
    		{
    			string extension = Path.GetExtension( fileName );
    			string nameWithoutExtension = Path.GetFileNameWithoutExtension( fileName );
    			int count = 1;
    			while ( File.Exists( Path.Combine( folderPath, fileName ) ) )
    			{
    				fileName = nameWithoutExtension + "-" + count + extension;
    				count++;
    			}
    		}
    		return fileName;
    	}
    }

  2. #2
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut
    Je me répond à moi-même pour ceux qui passerais par ici et que ça intéresserait

    En fait le problème provenait que au moment de la création du fichier celui n'était pas fermé dans le lock pour l'écriture au moment du download.

    La correction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    lock( padlock )
    		{
    			fileName = CreateFileName( pathWhereSave, fileName );
    			File.Create( Path.Combine(Path.Combine( pathWhereSave, fileName ) ).Close;
    		}

  3. #3
    Membre éprouvé
    Homme Profil pro
    Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique
    Inscrit en
    Décembre 2014
    Messages
    449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur Systèmes, Clouds et Réseaux /CAO/DAO/Ingénierie Electrotechnique

    Informations forums :
    Inscription : Décembre 2014
    Messages : 449
    Points : 991
    Points
    991
    Par défaut
    Salut;

    Permets moi de rajouter un point sur les threads et les fichiers, après je n'ai pas tenté sur des SSD, mais sur des disques durs à plateaux je me suis aperçu que c'était une erreur, je pensais améliorer mes performances alors qu'elles ont chuté, éventuellement en bossant avec des informations vraiment hardware sur des partitions reposant sur plusieurs disques on pourrait peut être améliorer mais je ne parierai pas et je pense qu'il faudrait passer même pas du c++/cli ou équivalent.
    D'une manière générale même, à part si c'est simplement pour éviter un processus bloquant le multitask/multithread n'est pas forcément un avantage comme on pourrait le penser, ça a un coût, d'ailleurs le tuto sur ce forum en parlait et j'avais du mal à imaginer ça et pour avoir expérimenté ça je me susi rendu compte qu'il fallait bien penser son code avant et bien réfléchir avant si c'était vraiment susceptible d'amener à un gain en performances sans quoi on arrive à un effet totalement inverse.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme de création de fichiers avec une boucle
    Par bobo696 dans le forum Débuter
    Réponses: 3
    Dernier message: 19/01/2009, 14h45
  2. Probleme de création de fichier dans un fs
    Par cybersplash dans le forum Linux
    Réponses: 1
    Dernier message: 25/11/2007, 16h46
  3. probleme de création de fichier .iso
    Par nabians dans le forum Autres Logiciels
    Réponses: 5
    Dernier message: 29/07/2007, 13h15
  4. Réponses: 1
    Dernier message: 19/03/2007, 20h57
  5. [FTP] Probleme de droits création fichier
    Par kahya dans le forum Langage
    Réponses: 2
    Dernier message: 09/06/2006, 10h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo