Модераторы: diadiavova, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> не работает DownloadFileAsync 
V
    Опции темы
s180
Дата 2.11.2009, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



новичок в программировании на .NET. Надо скачать файл из интернета, использую следущий код:

   
Код

 Dim WithEvents instanc As WebClient = New WebClient()
    Sub Main()

        Dim fileName, address As String
        address = "http://open-book.ru/uploads/posts/2009-03/thumbs/1236444235_6.0-enterprise-sp6.png"
        Dim uri As Uri = New Uri(address)
        Dim value As New WebProxy

        AddHandler instanc.DownloadFileCompleted, AddressOf qw

        instanc.DownloadFileAsync(uri, "C:\jpegs\1.jpg")

    End Sub


почему-то картинка скачивается 0Кб, и Event'ов никаких не возникает. Метод instanc.DownloadFile работает (но надо указать Proxy: instanc.Proxy = value), а DownloadFileAsync не хочет, в чём может быть проблема.

Это сообщение отредактировал(а) diadiavova - 2.11.2009, 15:21
PM MAIL   Вверх
diadiavova
Дата 2.11.2009, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Вот этот код загрузит файл на рабочий стол и по окончании загрузки отобразит его в пикчербоксе
Код

Imports System.Net

Public Class Form1
    Dim WithEvents instanc As New WebClient
    Dim imgpath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "/imd.png"
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim uri As Uri = New Uri("http://open-book.ru/uploads/posts/2009-03/thumbs/1236444235_6.0-enterprise-sp6.png")
        instanc.DownloadFileAsync(uri, imgpath)
    End Sub

    Private Sub instanc_DownloadProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs) Handles instanc.DownloadProgressChanged
        If e.ProgressPercentage = 100 Then
            Me.PictureBox1.Image = Image.FromFile(imgpath)
        End If
    End Sub
End Class




--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 2.11.2009, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



спасибо! действительно работает! ещё вопрос. мне надо с определённым промежутком времени сохранять 10 файлов из разных мест, промежуток для всех разный. Где-то 1мин, где-то час. Лучше использовать потоки для такой задачи? если можно небольшой пример.
PM MAIL   Вверх
s180
Дата 2.11.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



Ещё Вы писали о том как сделать чтобы скачивалось одновременно несколько файлов.

 Файл конфигурации находится в папке проекта и называется app.config. Это XML - lокумент, его надо открыть в XML-редакторе и добавить в корневой элемент секцию следующего содержания

Код

   <system.net>
    <connectionManagement>
      <add address="*" maxconnection="100"/>
    </connectionManagement>
  </system.net>

 
Не могу найти этот файл в папке проекта, где он может быть ещё?

Это сообщение отредактировал(а) diadiavova - 2.11.2009, 15:21
PM MAIL   Вверх
diadiavova
Дата 2.11.2009, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Я бы реализовал это в виде списка заданий. Расклад примерно следующий:
Создаётся класс, представляющий задачу, в нём есть свойство, указывающие время очередной закачки, интервал между закачками, и адрес картинки. Так же можно создать метод, котороый автоматически будет прибавлять интервал ко времени.
Далее, для каждой картинки создаётся такой объект со всеми данными и из них формируется коллекция.
Добавляем в форму таймер и на каждом тике таймера проверяем, есть ли картинки, которые пора обновлять. Если такие находятся, то обновляем и добавляем ко времени очередной загрузки интервал между загрузками.

А файл конфигурации можно добавить в проект если его там нет. Диалог "Добавить новый элемент"

Добавлено через 37 секунд
И не забывай пользоваться тегом "Код"


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 2.11.2009, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



Цитата(diadiavova @ 2.11.2009,  15:20)
Далее, для каждой картинки создаётся такой объект со всеми данными и из них формируется коллекция.

а для чего надо создавать коллекцию?

правильно ли понимаю, что надо использовать Task Class из System.Threading.Tasks?
т.к. проект у меня "бесформенный" можно ли использовать таймер в нём?
PM MAIL   Вверх
diadiavova
Дата 2.11.2009, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  2.11.2009,  15:47 Найти цитируемый пост)
System.Threading.Tasks

 smile Что это?
Цитата(s180 @  2.11.2009,  15:47 Найти цитируемый пост)
а для чего надо создавать коллекцию?
Ну я так понял у тебя есть набор задач . Для каждой создаётся объект и их надо где-то хранить.
Кстати, если надо грузить всё асинхронно и это принципиально, то лучше сделать не так как я в первый раз написал, а просто зашивать таймер и вебклиентв каждый такой объект. Вот примерный набросок класса задания. Код не для копипасты и вряд ли сразу заработает, а просто для того, чтобы наглядно показать, что я имею в виду
Код

Imports System.Net

Public Class ImageUpdateTask
    Dim WithEvents _webClient As New WebClient
    Dim WithEvents _timer As New Timers.Timer

    Public Sub Start()
        If Not _timer.Enabled Then
            _timer.Start()
        End If
    End Sub

    Public Sub [Stop]()
        If _timer.Enabled Then
            _timer.Stop()
        End If
    End Sub

    Private Sub _webClient_DownloadProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs) Handles _webClient.DownloadProgressChanged
        If e.ProgressPercentage = 100 Then
            _timer.Start()
        End If
    End Sub

    Private Sub _timer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _timer.Elapsed
        _webClient.DownloadFileAsync(Me.SourceImagePath, Me.DestImagePath)
    End Sub

    Dim _sourceImagePath As Uri
    Public Overridable Property SourceImagePath() As System.Uri
        Get
            Return _sourceImagePath
        End Get
        Set(ByVal value As System.Uri)
            _sourceImagePath = value
        End Set
    End Property

    Dim _destImagePath As String
    Public Overridable Property DestImagePath() As String
        Get
            Return _destImagePath
        End Get
        Set(ByVal value As String)
            _destImagePath = value
        End Set
    End Property
    Dim _updateInterval As TimeSpan
    Public Overridable Property UpdateInterval() As System.TimeSpan
        Get
            Return _updateInterval
        End Get
        Set(ByVal value As System.TimeSpan)
            _updateInterval = value
        End Set
    End Property

    Public Sub New(ByVal source As String, ByVal dest As String, ByVal interval As Double)
        With _timer
            .AutoReset = False
            .Interval = interval
        End With
        Me.SourceImagePath = New Uri(source)
        Me.DestImagePath=dest)
    End Sub
End Class



Это сообщение отредактировал(а) diadiavova - 2.11.2009, 16:52


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 2.11.2009, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



часть понял, но почему-то у меня ничего не переписывается, вызываю таким кодом:

Код

        Dim x As New ImageUpdateTask
        While True
            x.Start()
            x.New("http://open-book.ru/uploads/posts/2009-03/thumbs/1236444235_6.0-enterprise-sp6.png", "C:\Jpegs\1.jpg", 30000)
        End While

PM MAIL   Вверх
s180
Дата 2.11.2009, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



всё!! я окончательно запутался!! теперь и первый ваш класс, который Вы написали скачивает файл размером 0 байт!
PM MAIL   Вверх
diadiavova
Дата 2.11.2009, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  2.11.2009,  17:05 Найти цитируемый пост)
 x.New("http://open-book.ru/uploads/posts/2009-03/thumbs/1236444235_6.0-enterprise-sp6.png", "C:\Jpegs\1.jpg", 30000)

Что это? smile 

Код

        Dim x As New ImageUpdateTask( _
"http://open-book.ru/uploads/posts/2009-03/thumbs/1236444235_6.0-enterprise-sp6.png", _
"C:\Jpegs\1.jpg", 30000)
        x.Start()
И всё. Ну и соответственно повторюсь
Цитата(diadiavova @  2.11.2009,  16:28 Найти цитируемый пост)
Код не для копипасты и вряд ли сразу заработает, а просто для того, чтобы наглядно показать, что я имею в виду




--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
diadiavova
Дата 2.11.2009, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Вот сопсно рабочий пример. Сохраняет на рабочий стол каждые 10 секунд, и в NumericUpDown при каждом обновлении увеличивает число на 1.

То есть для каждой картинки по такому объекту создай и всё должно работать.

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  DownloadFileAsync.rar 462,71 Kb


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 3.11.2009, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



спасибо большое, работает. Но понять не могу, у меня скачивается файл 0Кб! почему такое происходит? может это из-за Proxy? просто DownloadFile качает нормально при указании строчек:

Код

Dim WithEvents instanc As WebClient = New WebClient()
Dim value As New WebProxy
instanc.Proxy = value


а DownloadFileAsync не хочет. Как быть?

Это сообщение отредактировал(а) s180 - 3.11.2009, 09:33
PM MAIL   Вверх
diadiavova
Дата 3.11.2009, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Это свойство указывает прокси-сервер. А просто объект без параметров естественно работать и не должен.
Кстати, там в примере свойство UpdateInterval надо или убрать или переписать. Это свойство-пустышка, ничего не делает. Поначалу хотел сделать по-другому и ввёл его, а потом не использовал. smile 


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 3.11.2009, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



ещё вопрос. мне заранее неизвестно какое количество файлов мне надо качать, я беру это каждый раз из базы (с этим, слава Богу, я сам справился). Как объявлять объект созданного класса при чтении строки из базы, т.е. читаем строку - создаём класс?
PM MAIL   Вверх
diadiavova
Дата 3.11.2009, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Не совсем понял вопрос. 
Для каждой картинки которую надо обновлять из сети через определённые промежутки времени надо создать свой экземпляр класса, указав параметры. Хранить экземпляры надо в специальной коллекции. То есть: Считываются данные из базы, на их основе создаётся экземпляр класса и добавляется в коллекцию, откуда всегда можно получить к нему доступ. 


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 3.11.2009, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



да. Т.е. я сначала считываю информацию из базы, о количестве файлов и промежутках через которые их надо сохранять, затем создаю вот таким образом экземпляры класса:

Код

Dim task(0) As Object
'''''''считываю количество файлов и записываю в FilesCount
ReDim Preserve task(FilesCount)
For i=1 to FilesCount
   task(i) = New ImageUpdateTask(RS.Fields("SOURCE").Value, RS.Fields("DESTINATION").Value, CDbl(RS.Fields("DAYINT").Value)))
   task(i).Start()
End For


и ничего опять не работает(( и я так понимаю при таком создании экземпляры класса будут работать без Event'ов?

Это сообщение отредактировал(а) s180 - 3.11.2009, 15:53
PM MAIL   Вверх
diadiavova
Дата 3.11.2009, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Во-первых работатьб смассивом таким образом не есть хорошо. Используй List(Of ImageUpdateTask)
Код

Dim tasks = New List(Of ImageUpdateTask)
Dim newTask = New ImageUpdateTask(RS.Fields("SOURCE").Value, RS.Fields("DESTINATION").Value, CDbl(RS.Fields("DAYINT").Value)))
tasks.Add(newTask)
newTask.Start()

Во-вторых, я не знаю, что там у тебя база выдаёт. По идее должно работать, а для того, чтобы события как-то отрабатывали на них подписаться надо.

Добавлено через 2 минуты и 41 секунду
Да и ещё...первую строчку кода надо вписать в код класса, а то что за ней - в код процедуры
Код

Dim tasks = New List(Of ImageUpdateTask)
Sub InitTasks()
    Dim newTask = New ImageUpdateTask(RS.Fields("SOURCE").Value, RS.Fields("DESTINATION").Value, CDbl(RS.Fields("DAYINT").Value)))
    tasks.Add(newTask)
    newTask.Start()
End Sub



--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 3.11.2009, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



Цитата

Во-вторых, я не знаю, что там у тебя база выдаёт. По идее должно работать, а для того, чтобы события как-то отрабатывали на них подписаться надо.


база выдаёт всё как положенно, проверил несколько раз. 

Цитата

Код

Dim tasks = New List(Of ImageUpdateTask)



это вписал в код класса.

как подписаться на события? с помощью WithEvents? видимо у меня не отрабатывает событие _timer_Elapsed, раз он скачивать не хочет.

PM MAIL   Вверх
diadiavova
Дата 3.11.2009, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  3.11.2009,  16:18 Найти цитируемый пост)
как подписаться на события?

А у меня в примере разве не было подписки на события?
Код

AddHandler объект.событие, AddressOf имяОбработчикаСобытия

http://msdn.microsoft.com/ru-ru/library/7taxzxka.aspx

Цитата(s180 @  3.11.2009,  16:18 Найти цитируемый пост)
база выдаёт всё как положенно

А как положено? В каком формате она выдаёт адреса, например?


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 3.11.2009, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



кажется разобрался...

Это сообщение отредактировал(а) s180 - 3.11.2009, 16:44
PM MAIL   Вверх
s180
Дата 5.11.2009, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



возник ещё вопросы.

1. позволяет ли данный метод ловить например обрыв связи при скачивании файла, или какие-нибудь другие ошибки?
2. в процессе экспериментов оказалось, что такая реализация не подходит, т.к. при сохранении файлов интервал не выдерживается, т.е. опоздания с сохранением получаются от 1 до 4 сек. естесственно за сутки может набежать немалое время разницы. Если использовать потоки поможет ли это улучшить ситуацию?

Это сообщение отредактировал(а) s180 - 5.11.2009, 11:31
PM MAIL   Вверх
diadiavova
Дата 5.11.2009, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  5.11.2009,  10:03 Найти цитируемый пост)
1. позволяет ли данный метод ловить например обрыв связи при скачивании файла, или какие-нибудь другие ошибки?

Надо поэксперементировать с событиями. Например завершение загрузки произошло, а процент загруженных данных меньше ста. Я тут точно сказать не могу. Надо пробовать.

Цитата(s180 @  5.11.2009,  10:03 Найти цитируемый пост)
в процессе экспериментов оказалось, что такая реализация не подходит, т.к. при сохранении файлов интервал не выдерживается, т.е. опоздания с сохранением получаются от 1 до 4 сек. естесственно за сутки может набежать немалое время разницы.

Просто я так всё устроил, что новый интервал начинает отсчитываться только по завершении загрузки файла. Можно сделать так, чтобы это происходило строго через заданный интервал.
Цитата(s180 @  5.11.2009,  10:03 Найти цитируемый пост)
Если использовать потоки поможет ли это улучшить ситуацию?

Они и так используются, только неявно.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 5.11.2009, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



Цитата(diadiavova @  5.11.2009,  12:36)
Просто я так всё устроил, что новый интервал начинает отсчитываться только по завершении загрузки файла. Можно сделать так, чтобы это происходило строго через заданный интервал..

да, это я понял и переделал, вот сейчас тестирую как раз. может ситуация улучшится.

Цитата(diadiavova @  5.11.2009,  12:36)

Они и так используются, только неявно.

т.е. использование, например, BackgroundWorker ситуацию в явно лучшую сторону не поменяет?

и ещё при первом запуске выдаётся: WebClient does not support concurrent I/O operations на строчке DownloadFileAsync, но при нажатии несколько раз. программа продолжает работать, т.е. видимо при запуске происходит какой-то "косяк". В чём может быть проблема? появилось после того как убрал флаг у таймера выполнения только один раз.

Это сообщение отредактировал(а) s180 - 5.11.2009, 13:22
PM MAIL   Вверх
diadiavova
Дата 5.11.2009, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  5.11.2009,  13:12 Найти цитируемый пост)
появилось после того как убрал флаг у таймера выполнения только один раз.

Там если этот флаг убирается, то надо убрать и код повторного запуска при окончании загрузки. Хотя скорее всего проблема в том, что предыдущая загрузка не завершена и даётся команда на новую. Возможно следует проверить завершена ли предыдущая загрузка.

Добавлено @ 14:01
Цитата(s180 @  5.11.2009,  13:12 Найти цитируемый пост)
т.е. использование, например, BackgroundWorker ситуацию в явно лучшую сторону не поменяет?

Я не понял какая сторона лучшая. Я ведь объяснил, что этот класс так работает потому, что так спроектирован.

Это сообщение отредактировал(а) diadiavova - 5.11.2009, 14:05


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 5.11.2009, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



Цитата(diadiavova @ 5.11.2009,  14:00)
Я не понял какая сторона лучшая. Я ведь объяснил, что этот класс так работает потому, что так спроектирован.

я имею ввиду, если использовать BackgroundWorker для этой задачи, это может поменять ситуацию?
PM MAIL   Вверх
diadiavova
Дата 5.11.2009, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  5.11.2009,  14:14 Найти цитируемый пост)
я имею ввиду, если использовать BackgroundWorker для этой задачи, это может поменять ситуацию?

В какую сторону её надо поменять? Иными словами : чего ты хочешь добиться его использованием? Загрузка и так происходит в отдельном потоке.
Сформулируй более точно, что сейчас не так и какие изменения ты хочешь ввести. Правда сразу следует оговориться, что тут есть ряд нюансов. 
Ты не можешь обновлять один и тот же файл одновременно из двух потоков. 
Завязав логику соблюдения интервалов между началом обновления ты закладываешь в код грабли. У конечного пользователя просто-напросто доступ к интернету может быть более скромным и за тот промежуток времени, который ты отмеришь, прога не успеет обновить файл даже один раз. В результате ты получишь сбой. Хотя мне вообще не совсем понятно зачем начинать новое обновление, когда ещё старое не завершено.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 6.11.2009, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



спустя 20 мин. работы, программа выдаёт сообщение:

The CLR has been unable to transition from COM context 0x20c058 to COM context 0x20c1c8 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

и после чего вылетает. Никто не сталкивался, как с этим бороться?
PM MAIL   Вверх
s180
Дата 6.11.2009, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



прочитал на MSDN'е, что такой exception можно отключить:

Цитата

You can try to disable this specific MDA as a workaround. 

In Visual Studio, goto “Debug” -> “Exceptions…” menu
Open the Managed Debugging Assistants tree 
Uncheck ContextSwitchDeadlock

PM MAIL   Вверх
s180
Дата 6.11.2009, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



ничего не могу понять. почему промежуток сохранения файлов продолжает расти?

вот код:

Код

Private Sub _timer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _timer.Elapsed

        Me.Filename = Format(TimeOfDay, "HH-mm-ss") + ".jpg"
        _webClient.DownloadFileAsync(Me.SourceImagePath, Me.DestImagePath+ Me.Filename)
.............


так вот в итоге у меня получается, что сохраняются файлы:
14-25-50.jpg
14-30-50.jpg
14-35-50.jpg
14-40-51.jpg
14-45-51.jpg
14-50-51.jpg
14-55-51.jpg
15-00-51.jpg
...

через какое-то время может ещё на секунду увеличится, т.е. получается, что если так будет сохраняться, то время сохранения будет существенно отличатся от того, что надо. Я так понимаю, что время начала закачки почему-то сдвигается, хотя работает по событию таймера.

Это сообщение отредактировал(а) s180 - 6.11.2009, 14:45
PM MAIL   Вверх
s180
Дата 6.11.2009, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



в общем, путём экспериментов выяснилось, что событие _timer_Elapsed, срабатывает не в точное время. При чтении свойства ElapsedEventArgs.SignalTime выясняется, что сработка происходит не каждые, например 2000мс, а 2159 или 2005мс и т.д. Т.е. если у нас _timer.Interval=2000, то смотрим как происходит запись файлов:

1. ElapsedEventArgs.SignalTime=2005
2. ElapsedEventArgs.SignalTime=2005+2000+погрешность
....

Поэтому пока решил после каждого события уменьшать _timer.Interval на ElapsedEventArgs.SignalTime.Millisecond. Посмотрим, что выйдет.
PM MAIL   Вверх
s180
Дата 11.11.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



результаты экспериментов:

таймер работает неверно!!!!! при любом интервале, в событии timer_Elapsed я логгирую время срабатывания и каждый раз это время, то уменьшается, то увеличивается. Интервал срабатывания не выдерживается!!! За сутки разница первого срабатывания, по сравнению с последним может состоять до нескольких минут!! 

возможны ли какие-нибудь другие варианты, кроме "кривого" таймера?

Это сообщение отредактировал(а) s180 - 11.11.2009, 10:17
PM MAIL   Вверх
diadiavova
Дата 11.11.2009, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Я, конечно, не проверял таймер в работе, но не исключаю, что причина в том, что время загрузки просто перкрывается. То есть не закончилась первая, начинается вторая и поток вынужден ждать очереди.
Если таймер в самом деле работает нечётко, то тут трудно что-либо придумать. Возможно следует вернуться к первому варианту, где загрузка будет координироваться из одного потока, а объекты задач будут только содержать информацию о том когда пора обновиться. Но реализовать это несколько сложнее. Можно попробовать укоротить интервалы (например вдвое) и всякий раз при срабатывании таймера просто сверяться со временем и определять пора обновляться или нет. Тут варианты разные, но что лучше з зависит от задачи, да и пробовать надо разные варианты, чтобы можно было выявить лучший.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 11.11.2009, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



Цитата

Я, конечно, не проверял таймер в работе, но не исключаю, что причина в том, что время загрузки просто перкрывается. То есть не закончилась первая, начинается вторая и поток вынужден ждать очереди.


интервалы минимум двухминутные, а размер скачиваемого файла меньше 50Kb, думаю время не может перекрываться. Да даже дело не в этом, я просто записываю в текстовый файл время срабатывания и разница у них точно не равняется интервалу! причём, ладно бы она всегда увеличивается, так она ещё и уменьшатсья может!!! т.е. срабатывает например не через 120 секунд а через 118,560!!! как такое может быть??
PM MAIL   Вверх
diadiavova
Дата 11.11.2009, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



s180, а если просто таймером щёлкать без закачки результат такой же?

Влюбом случае вариант, при котором щелчки таймера будут только сигналом для проверки необходимости закачки, решит проблему. Суммарная погрешность за любой промежуток времени не превысит интервала таймера.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 12.11.2009, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



Код

Public Class TestTimer
    Dim WithEvents timer As New Timers.Timer
    Dim ltime As Integer

    Public Sub Start()
        timer.Interval = 1000
        Me.Ltime = 20
        timer.Enabled = True
    End Sub

    Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles timer.Elapsed
        Dim fs As New Scripting.FileSystemObject
        Dim ts As Scripting.TextStream
        Me.Ltime = Me.Ltime - 1
        If Me.Ltime = 0 Then
            ts = fs.OpenTextFile("c:\1.txt", Scripting.IOMode.ForAppending, True)
            ts.WriteLine(Format(e.SignalTime, "HH-mm-ss-fff"))
            ts.Close()
            Me.Ltime = 20
        End If
    End Sub
    Public Overridable Property Ltime() As Integer
        Get
            Return ltime
        End Get
        Set(ByVal value As Integer)
            ltime = value
        End Set
    End Property
    Public Sub New(ByVal Lt As Integer)
        Me.Ltime = Lt
    End Sub
End Class


вот как проверял таймер. результаты вот какие:

17-52-00-853
17-52-20-845
17-52-40-837
17-53-00-829
17-53-20-821
17-53-40-812
17-54-00-804
...

здесь получается, что каждый раз срабатывает на 8мс раньше, в других случаях бывает, что он наоборот бежит вперёд!!

Добавлено через 2 минуты и 19 секунд
Цитата(diadiavova @ 11.11.2009,  17:40)
Влюбом случае вариант, при котором щелчки таймера будут только сигналом для проверки необходимости закачки, решит проблему. Суммарная погрешность за любой промежуток времени не превысит интервала таймера.

к сожалению не решают, вот сейчас пробую вариант, не с секундным интервалом, а с 200мс, посмотрим может там какие результаты будут.
PM MAIL   Вверх
diadiavova
Дата 12.11.2009, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  12.11.2009,  09:56 Найти цитируемый пост)
к сожалению не решают, вот сейчас пробую вариант, не с секундным интервалом, а с 200мс, посмотрим может там какие результаты будут. 

Судя по всему, ты не понял идею. Я говорю о варианте, при котором точность секундомера вообще не будет играть роли. Расклад примерно такой:
У тебя в классе задания должны присутствовать свойства например
NextUpdateTime As DateTime
 и
UpdateInterval As TimeSpan

Интервал таймера ставишь на величину равную предельно-допустимой погрешности работы задачи за всё время работы программы. То есть, если тебе надо чтобы за время работы программы ошибка во времени не превышала 10 секунд, то и ставь таймер на такое время.

Всякий раз, когда срабатывает таймер выполняешь следующее действие
    Проверяешь наступило ли время очередного обновления(сравниваешь текущее время со значением   
    NextUpdateTime) и если наступило, то сначала выполняешь загрузку, а затем к значению 
    NextUpdateTime прибавляешь UpdateInterval и таким образом планируешь время следующего 
    обновления.

То есть обновление будет происходить не при каждом щелчке, а только тогда, когда уже наступило запланированное время и в этом случае планируется время нового обновления.

Надеюсь объяснил понятно.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 12.11.2009, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



так я так и делаю. в коде я так и написал, устанавливаю интервал "тиканья" 1с, при каждом тике уменьшаю свойство-время на 1с и когда она станет равна 0 записываю в текстовый файл. При 200мс получается вроде неплохо, но когда увеличил, время срабатывания с 20с до 5 минут, погрешность стала сотсавлят 5с!!!!!
PM MAIL   Вверх
diadiavova
Дата 12.11.2009, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 8
Всего: 142



Цитата(s180 @  12.11.2009,  10:54 Найти цитируемый пост)
при каждом тике уменьшаю свойство-время на 1с и когда она станет равна 0 записываю в текстовый файл.

Это ещё зачем? Я ведь не так написал. При тике просто проверяй пора обновляться или нет. Если пора - обновляйся и устанавливай время нового обновления. И всё.


--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
s180
Дата 16.11.2009, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 2.11.2009

Репутация: нет
Всего: нет



всё. наконец-то всё отладил!! 

diadiavova, спасибо большое за помощь. Действительно, установил интервал таймера 200мс и проверял время следующего обновления, погрешность в мс составляла примерно +/- 300.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума VB .NET
diadiavova
  • Прежде чем задать вопрос, воспользуйтесь поиском: возможно Ваш вопрос уже обсуждался и на него был получен ответ.
  • Если такой же вопрос не найден, не стоит задавать свой вопрос в любую тему, создайте новую.
  • Заголовок темы должен отображать ее суть.
  • Содержание поста должно описывать проблему понятно, но в то же время, по возможности, лаконично. Сначала следует описать суть вопроса, потом можно привести пример кода, не вынуждайте других участников угадывать в чем Ваша проблема - телепатов здесь нет.
  • Будьте взаимно вежливы и дружелюбны.
  • При оформлении сообщений используйте форматирование, примеры кода заключайте в теги [CODE=vbnet][/CODE].
  • Также ознакомьтесь с общими правилами, действующими на всем форуме.
  • Если вопрос решен, не забывайте помечать тему решенной(вверху темы есть ссылка). Кроме того, если Вы хотите отблагодарить участников, оказавших помощь в решении, можно повысить им репутацию, в случае, если у Вас менее 100 сообщений в форуме и функция изменения репутации Вам недоступна, можете написать сюда.
  • Общие вопросы по программированию на платформе .NET обсуждаются здесь.
  • Литература по VB .NET обсуждается здесь.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, diadiavova.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | VB .NET | Следующая тема »


 




[ Время генерации скрипта: 0.1276 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.