Как закончить тему в win CF - PullRequest
       47

Как закончить тему в win CF

0 голосов
/ 02 сентября 2011

Windows Mobile 5; Компактный каркас и относительный новичок в c # и потоках.

Я хочу скачать большие файлы (несколько мегабайт) с моего собственного сайта; Будучи GPRS, это может занять некоторое время. Я хочу показать индикатор выполнения и разрешить отменить загрузку.

У меня есть класс с именем FileDownload и я создаю его экземпляр; укажите его и сохраните местоположение:

MyFileDownLoader.Changed += new FileDownLoader.ChangedEventHandler(InvokeProgressBar);

BGDownload = new Thread(new ThreadStart(MyFileDownLoader.DownloadFile));
BGDownload.Start();

Поэтому я создаю обработчик событий для обновлений индикатора выполнения и запускаю поток. Это отлично работает.

У меня есть кнопка отмены, которая гласит:

MyFileDownLoader.Changed -= InvokeProgressBar;
MyFileDownLoader.Cancel();
BGDownload.Join();
lblPercentage.Text = CurPercentage + " Cancelled"; // CurPercentage is a string
lblPercentage.Refresh();
btnUpdate.Enabled = true;

В классе FileDownload ключевые части:

public void Cancel()
{
    CancelRequest = true;
}

В методе Скачать файл:

...
success = false;
try {
//loop until no data is returned
while ((bytesRead = responseStream.Read(buffer, 0, maxRead)) > 0)
{
    _totalBytesRead += bytesRead;
    BytesChanged(_totalBytesRead);
    fileStream.Write(buffer, 0, bytesRead);
    if (CancelRequest)
       break;
}

if (!CancelRequest)
    success = true;
}
catch
{
    success = false;
    // other error handling code
}
finally
{
    if (null != responseStream)
        responseStream.Close();
    if (null != response)
        response.Close();
    if (null != fileStream)
        fileStream.Close();
}

// if part of the file was written and the transfer failed, delete the partial file
if (!success && File.Exists(destination))
    File.Delete(destination);

Код, который я использую для загрузки, основан на http://spitzkoff.com/craig/?p=24

Проблема, с которой я столкнулся, заключается в том, что когда я отменяю, загрузка немедленно останавливается, однако процесс присоединения может занять до 5 секунд или около того. Об этом свидетельствует lblPercentage.Text, обновляемый после объединения.

Если я тогда попытаюсь загрузить снова, иногда это работает, а иногда я получаю исключение нулевой ссылки (все еще пытаюсь отследить это).

Я думаю, что делаю что-то не так в своем подходе к отмене цепочки.

Я?

1 Ответ

1 голос
/ 02 сентября 2011
public void Cancel()
    {
        CancelRequest = true;
    }

Полагаю, вам следует добавить поточнобезопасное к этому действию.

public void Cancel()
        {
            lock (this)
            {
                CancelRequest = true;
            }
        }

Надеюсь, эта помощь!

...