Pergunta

Meu aplicativo estrutura compacta cria uma lista lisa-scrolling, tornando todos os itens para uma superfície bitmap grande, em seguida, copiar esse bitmap para uma posição compensada na tela de modo que apenas os itens apropriados mostrar. Versões mais antigas única prestados os itens que devem aparecer na tela no momento, mas esta abordagem foi muito lento para uma interface de rolagem suave.

Ele ocasionalmente gera um OutOfMemoryException quando inicialmente criar o bitmap grande. Se os executa usuário a-soft reset do dispositivo e executa o aplicativo novamente, ele é capaz de realizar a criação sem problema.

Ele não se parece com este bitmap está sendo gerado na memória do programa, uma vez que o aplicativo usa aproximadamente a mesma quantidade de memória do programa, como o fez antes os novos métodos suaves-scrolling.

Existe alguma maneira eu posso evitar essa exceção? Existe alguma maneira eu posso liberar a necessidade de memória I (onde quer que seja) antes a exceção é lançada?

Foi útil?

Solução

Eu sugiro volta ao velho mecanismo de processar apenas parte dos dados indo, como o tamanho dos dados totalmente prestados é, obviamente, um problema. Para ajudar a evitar problemas de renderização eu provavelmente pré-render algumas linhas acima e abaixo da vista atual para que possam ser "enrolado" com impacto limitado.

Outras dicas

E assim que eu postei Pensei em algo que você pode fazer para resolver o seu problema com a nova versão. O problema que você tem é um dos CF tentando encontrar um bloco de memória contígua disponível para o enorme bitmap, e este é ocasionalmente um problema.

Em vez de criar um grande bitmap, você pode em vez criar uma coleção de bitmaps menores, uma para cada item, e tornar cada item para o seu próprio pequeno bitmap. Durante a visualização, você em seguida, basta copiar os bitmaps que você precisa. CF terá um tempo muito mais fácil criar um monte de pequenos bitmaps de um grande problema, e você não deve ter quaisquer problemas de memória, a menos que este é um verdadeiramente enorme monte de itens.

Eu deveria evitar expressões como "não há nenhuma solução".

Um outro ponto importante: certifique-se de chamar Dispose () em cada bitmap quando tiver terminado com ele

.

Seu bitmap definitivamente é que está sendo criado na memória de programa. Quanta memória as necessidades de bitmap depende de quão grande ele é, e se ou não este tamanho necessário irá gerar o OutOfMemoryException depende de quanto está disponível para o PDA (o que torna este um erro aleatoriamente ocorrendo).

Desculpe, mas isso é geralmente uma técnica de renderização de controle desaconselhável (especialmente no Compact Framework) para o qual não há solução a curto de aumentar a memória física no PDA, que geralmente não é possível (e muitas vezes não vai resolver o problema de qualquer maneira, uma vez que um processo CF é limitado a 32MB não importa o quanto o dispositivo tem disponível).

Sua melhor aposta é a de voltar para a versão antiga e melhorar a sua velocidade de renderização. Há também uma técnica simples disponíveis no CF para fazer um controle de buffer duplo para eliminar cintilação.

Uma vez que parece que você topar com uma limitação dispositivo que está restringindo o tamanho total do espaço de Bitmap você pode criar (estes são aparentemente criado na RAM de vídeo em vez de memória geral do programa), uma alternativa é substituir o objeto Bitmap grande usado aqui com um bloco simples de idade de memória do Windows, acessando-o para ler e escrever por PInvoking a função BitBlt API.

Inicialmente criar o bloco de memória é complicado, e você provavelmente gostaria de fazer outra pergunta SO sobre isso (GCHandle.Alloc pode ser usado aqui para criar um "preso" objeto, o que significa .NET não é permitido movimento -lo ao redor na memória, o que é fundamental aqui). Eu sei como fazê-lo, mas eu não tenho certeza se eu fazê-lo corretamente e eu prefiro ter a entrada de um especialista.

Depois de criar o bloco grande, você iterar seus itens, renderizar cada a um pequeno bitmap que você mantenha re-usando (usando o código .NET existente) e BitBlt-lo para o local apropriado na sua memória bloco.

Depois de criar todo o cache, o seu código de renderização deve funcionar como antes, com a diferença de que em vez de copiar a partir do grande bitmap a sua superfície de renderização, você BitBlt do seu bloco de cache. Os argumentos para BitBlt são essencialmente os mesmos que para DrawImage (destino, fonte, coordenadas e tamanhos etc.).

Uma vez que você está criando o cache de memória regular, desta forma, em vez de RAM de vídeo especializado, eu não acho que você vai correr para o mesmo problema. No entanto, eu definitivamente obter o código de criação de bloco trabalhando em primeiro lugar e de teste para se certificar de que pode criar um bloco grande o suficiente de cada vez.

Update: na verdade, a abordagem ideal seria ter uma coleção de blocos de memória mais pequenos em vez de um grande (como eu achava que era o problema com a abordagem Bitmap), mas você já tem o suficiente para fazer. Eu já trabalhei com CF aplicativos que lidam com 5 e 10MB objetos e não é um grande problema de qualquer maneira (embora possa ser um problema maior quando esse pedaço é preso - eu não sei). BTW, eu sempre fui surpreendido pelos Oomes na criação BitMap porque eu sabia que os bitmaps eram muito menores do que a memória disponível, assim como você - agora eu sei porquê. Desculpe, eu pensei que este era um fácil resolver em primeiro lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top