none
Распаралеливание запроса Foreach. RRS feed

  • Вопрос

  • Здравствуйте,подскажите пожалуйста, как можно распаралелить выполнение данного запроса:

    private void DownloadAllTorrents(MatchCollection res)
            {
                foreach (var x in res)
                {
                    string id = Regex.Match(x.ToString(), @"([0-9]+)").ToString();
                    byte[] torrent = GetTor(Int64.Parse(id));
    
                    Debug.WriteLine("{0}", id);
    
                    FileStream fs = new FileStream(String.Format(@"D:\Torrents\{0}.torrent", id), FileMode.Create, FileAccess.Write);
                    fs.Write(torrent, 0, torrent.Length);
                    fs.Close();
    
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate { now.Value++; });
                }
            }
    Заранее благодарен за внимание.

    DreamSpark Premium User

    25 ноября 2012 г. 23:41

Ответы

  • Кстати, Алексей, Ваш метод не сработал, пишет ошибку об ошибке приведения типов. Сделал проще:

                var res = pattern.Matches(s);
                List<string> links = new List<string>();
    
                foreach (var x in res)
                {
                    links.Add(x.ToString());
                }
    
                Task downloaded = new Task(() => DownloadAllTorrents(links.ToArray()));
                downloaded.Start();

    И сам метод:

            private void DownloadAllTorrents(string[] res)
            {
                Parallel.ForEach(res, x => 
                {
                    string id = Regex.Match(x, @"([0-9]+)").ToString();
                    byte[] torrent = GetTor(Int64.Parse(id));
                    Debug.WriteLine("{0}", id);
                    FileStream fs = new FileStream(String.Format(@"D:\Torrents\{0}.torrent", id), FileMode.Create, FileAccess.Write);
                    fs.Write(torrent, 0, torrent.Length);
                    fs.Close();
    
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate { now.Value++; });
                });
    
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate 
                { 
                    now.Value = 0;
                    MessageBox.Show("Завершено!", "Ня! ^_^");
    
                });
            }


    DreamSpark Premium User

    26 ноября 2012 г. 9:09

Все ответы

  • http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx

    http://msdn.microsoft.com/ru-ru/library/dd413237.aspx

    сам не пользовался, но похоже по названию.

    Некоторую неуверенность внсит строка
    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate { now.Value++; });

    Новый поток какой-то запускается, из потока (если распараллелить).
    Ну там наверное всё синхронизировано.

    26 ноября 2012 г. 4:42
  • Можно записать вот так:

    res.AsParallel().ForAll(x =>
                {
                    string id = Regex.Match(x.ToString(), @"([0-9]+)").ToString();
                    byte[] torrent = GetTor(Int64.Parse(id));
                    Debug.WriteLine("{0}", id);
                    FileStream fs = new FileStream(String.Format(@"D:\Torrents\{0}.torrent", id), FileMode.Create, FileAccess.Write);
                    fs.Write(torrent, 0, torrent.Length);
                    fs.Close();
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate { now.Value++; });
                });

    Единственно, надеюсь у вас now.Value потокобезопасная?
    • Помечено в качестве ответа asdfxcbneftyherwe 26 ноября 2012 г. 6:41
    • Снята пометка об ответе asdfxcbneftyherwe 26 ноября 2012 г. 9:17
    26 ноября 2012 г. 6:16
    Отвечающий
  • Можно записать вот так:

    res.AsParallel().ForAll(x =>
                {
                    string id = Regex.Match(x.ToString(), @"([0-9]+)").ToString();
                    byte[] torrent = GetTor(Int64.Parse(id));
                    Debug.WriteLine("{0}", id);
                    FileStream fs = new FileStream(String.Format(@"D:\Torrents\{0}.torrent", id), FileMode.Create, FileAccess.Write);
                    fs.Write(torrent, 0, torrent.Length);
                    fs.Close();
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate { now.Value++; });
                });

    Единственно, надеюсь у вас now.Value потокобезопасная?

    now.Value++ это увеличение на единицу текущей позиции прогресс-бара. Не знаю как там с потокобезопасностью.


    DreamSpark Premium User

    26 ноября 2012 г. 6:40
  • А, не, все должно быть нормально, вы же из одного и того же потока меняете.

    26 ноября 2012 г. 6:46
    Отвечающий
  • Кстати, Алексей, Ваш метод не сработал, пишет ошибку об ошибке приведения типов. Сделал проще:

                var res = pattern.Matches(s);
                List<string> links = new List<string>();
    
                foreach (var x in res)
                {
                    links.Add(x.ToString());
                }
    
                Task downloaded = new Task(() => DownloadAllTorrents(links.ToArray()));
                downloaded.Start();

    И сам метод:

            private void DownloadAllTorrents(string[] res)
            {
                Parallel.ForEach(res, x => 
                {
                    string id = Regex.Match(x, @"([0-9]+)").ToString();
                    byte[] torrent = GetTor(Int64.Parse(id));
                    Debug.WriteLine("{0}", id);
                    FileStream fs = new FileStream(String.Format(@"D:\Torrents\{0}.torrent", id), FileMode.Create, FileAccess.Write);
                    fs.Write(torrent, 0, torrent.Length);
                    fs.Close();
    
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate { now.Value++; });
                });
    
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate 
                { 
                    now.Value = 0;
                    MessageBox.Show("Завершено!", "Ня! ^_^");
    
                });
            }


    DreamSpark Premium User

    26 ноября 2012 г. 9:09
  • Не запускал, т.к. у меня нет вашей коллекции... А писать обертку было некогда.

    26 ноября 2012 г. 9:31
    Отвечающий