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

private void DoUpload()
    {
        foreach (UploadFile file in fileInfos)
        {
            int BUFFERSIZE = 1024;
            int offset = 0; //get from webservice, when partial file
            FileStream s = file.FileInfo.OpenRead();
            byte[] buffer = null;
            long remainingBytes = s.Length - offset;
            while (remainingBytes > 0)
            {
                if (remainingBytes < BUFFERSIZE)
                {
                    buffer = new byte[remainingBytes];
                    BUFFERSIZE = (int)remainingBytes;
                }
                else if (remainingBytes > BUFFERSIZE)
                {
                    buffer = new byte[BUFFERSIZE];
                }

                s.Read(buffer, 0, BUFFERSIZE);
                //push to webservice
                offset += BUFFERSIZE;
                int newPercentage = offset / (int)file.FileInfo.Length * 100;
                file.Percentage = newPercentage;
                remainingBytes = s.Length - offset;
                System.Threading.Thread.Sleep(10);
            }
            file.Percentage = 100;
            file.ImageSource = "accept.png";
        }
    }

UploadFile привязан к пользовательскому интерфейсу, поэтому изменения в этом файле будут отражаться в пользовательском интерфейсе. Проблема в том, что вся эта загрузка занимает слишком много времени (имитировала ее во сне), и во время этой связи пользовательский интерфейс не обновляется, нет никаких идей о том, как делать это?

0
H4mm3rHead 13 Ноя 2009 в 17:12

2 ответа

Лучший ответ

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

Если вам нужно изменить что-либо в пользовательском интерфейсе, это нужно сделать из потока пользовательского интерфейса. Поэтому, если вам нужно изменить пользовательский интерфейс, а ваш код выполняется в другом потоке, вы можете использовать метод Dispatcher.BeginInvoke для отправки операции в поток пользовательского интерфейса. Вы можете получить доступ к объекту Dispatcher приложения через: Deployment.Current.Dispatcher.

1
KeithMahoney 13 Ноя 2009 в 22:39

Я думал, что Silverlight разрешает только асинхронные вызовы. Если вы делаете что-то асинхронно, то использование Sleep вводит в заблуждение, поскольку загрузка не блокирует пользовательский интерфейс.

0
Joel Lucsy 13 Ноя 2009 в 17:29
Но если вызовы являются асинхронными, я не смогу сделать свою обратную связь, поскольку она возвращается незамедлительно? Как насчет обратных событий? Как узнать, какой файл является источником события возврата? учитывая, что я загружаю сразу несколько файлов?
 – 
H4mm3rHead
13 Ноя 2009 в 18:10