优化.Net Compact Framework中的位图加载

时间:2011-02-01 11:22:41

标签: c# optimization compact-framework

我需要在我的应用程序中加载一堆位图。问题是加载使表单非常慢。我的实际课程如下:

public class ImagensDisponiveis
{
    /// <summary>
    /// List of  ImagemSygic struct
    /// </summary>
    private List<ImagemSygic> _poolImagens;
    /// <summary>
    /// index of next avaiable image
    /// </summary>
    private int indiceProximoDisponivel;
    /// <summary>
    /// Path to image folder
    /// </summary>
    private string caminhoPasta;
    /// <summary>
    /// Number of found images that conforms to patterm
    /// </summary>
    private int MAXCOUNT;


    public ImagensDisponiveis(string caminhoPastaRecursos)
    {
        indiceProximoDisponivel = 0;
        caminhoPasta = caminhoPastaRecursos;

        PreencherPool(out _poolImagens, caminhoPasta);
        MAXCOUNT = _poolImagens.Count;
    }

    /// <summary>
    /// Preenche a lista de imagens com uma estrutura que contém a imagem e o caminho dessa imagem para o Sygic
    /// </summary>
    /// <param name="_poolImagens">The _pool imagens.</param>
    /// <param name="filepath">The filepath.</param>
    private void PreencherPool(out List<ImagemSygic> _poolImagens, string filepath)
    {
        DateTime momentoInicio = DateTime.Now;
        _poolImagens = new List<ImagemSygic>();
        string[] imagens = Directory.GetFiles(filepath);
#if DEBUG
        //int counter = 0;
        //int numFiles = imagens.Length;
#endif
        foreach (string caminhoImagem in imagens)
        {

            try
            {
                string filename = Path.GetFileName(caminhoImagem);
                //original image to show on .net [POI]anything.bmp
                //image that sygic tries to use on drive ?[POI]anything.bmp, where ? is an number between 1 to 6
                bool valido = filename.StartsWith("[POI]", StringComparison.InvariantCulture);
                //Log.writeToLog(caminhoImagem + " " + valido.ToString());
                if (valido)
                {

                    var streamImagem = File.Open(caminhoImagem, FileMode.Open, FileAccess.Read);
                    Bitmap temImagem = new Bitmap(streamImagem);
                    ImagemSygic tempImgSygic = new ImagemSygic();
                    tempImgSygic.CaminhoImagemSygic = caminhoImagem;
                    tempImgSygic.ImagemWindows = temImagem;
                    tempImgSygic.SygicImageID = -1;
                    _poolImagens.Add(tempImgSygic);
#if DEBUG
                    //counter++;

#endif
                }
            }
            catch (ArgumentException aec)
            {
                Log.writeToLog("[EXCEPCAO ImagensDisp]: ArgumentException - " + aec.Message);
            }
            catch (UnauthorizedAccessException uae)
            {
                Log.writeToLog("[EXCEPCAO ImagensDisp]: UnauthorizedAccessException - " + uae.Message);
            }

            catch (Exception exc)
            {
                Log.writeToLog("[EXCEPCAO ImagensDisp]: Exception - " + exc.Message);
            }
        }

        DateTime tempoFim = DateTime.Now;

        TimeSpan duracao = tempoFim.Subtract(momentoInicio);
        Log.writeToLog("[Criacao da pool] Demorou " + duracao.TotalSeconds.ToString());
    }
    /// <summary>
    /// OObtains the next avaianle ImagemSygic if there is an avaiable
    /// </summary>
    /// <returns>ImagemSygic if possible, else null</returns>
    public ImagemSygic ObterProximoDisponivel()
    {
        if (indiceProximoDisponivel > MAXCOUNT)
            return null;
        else
        {
            ImagemSygic imagemRetornar = _poolImagens[indiceProximoDisponivel];
            indiceProximoDisponivel++;
            return imagemRetornar;
        }
    }

    public void ResetCounter()
    {
        indiceProximoDisponivel = 0;
    }


}

/// <summary>
/// Class that contains the Bitmap preview and the original path to that image
/// </summary>
public class ImagemSygic
{

    private volatile int _imageID;
    /// <summary>
    /// Gets or sets the imagem windows.
    /// </summary>
    /// <value>The imagem windows.</value>
    public Bitmap ImagemWindows { get; set; }
    /// <summary>
    /// Gets or sets the caminho imagem sygic.
    /// </summary>
    /// <value>The caminho imagem sygic.</value>
    public string CaminhoImagemSygic { get; set; }

    /// <summary>
    /// Gets or sets the sygic image ID.
    /// </summary>
    /// <value>The sygic image ID.</value>
    public int SygicImageID
    {
        get
        {
            return this._imageID;
        }
        set
        {
            this._imageID = value;
        }
    }
}

/// <summary>
/// 
/// </summary>
public class POISygic
{

    private volatile int _latitude;
    private volatile int _longitude;
    /// <summary>
    /// Gets or sets the imagem.
    /// </summary>
    /// <value>The imagem.</value>
    public ImagemSygic Imagem { get; set; }
    /// <summary>
    /// Gets or sets the latitude.
    /// </summary>
    /// <value>The latitude.</value>
    public int Latitude { get { return this._latitude; } set { this._latitude = value; } }
    /// <summary>
    /// Gets or sets the longitude.
    /// </summary>
    /// <value>The longitude.</value>
    public int Longitude { get { return this._longitude; } set { this._longitude = value; } }
    /// <summary>
    /// Gets or sets the descricao.
    /// </summary>
    /// <value>The descricao.</value>
    public string Descricao { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether this instance is displayed now.
    /// </summary>
    /// <value>
    ///     <c>true</c> if this instance is displayed now; otherwise, <c>false</c>.
    /// </value>
    public bool isDisplayedNow { get; set; }

    /// <summary>
    /// Gets or sets the elem ID.
    /// </summary>
    /// <value>The elem ID.</value>
    public int elemID { get; set; }


}

本课程的目的是阅读一系列具有[POI]前缀的位图,以允许.net在窗体控件中显示一个图例,显示在Sygic Drive窗口中显示的poi图像。

问题是如何优化此代码以更快地加载图像。目前它在10秒内加载26个315k位图图像。但可能在最终的解决方案中,我们可以拥有多达+260个图像,因此这就是需要优化的原因。

1 个答案:

答案 0 :(得分:1)

我看到的最大潜在改进是PreencherPool加载文件夹中的所有图像。你是否一次显示所有图像?如果没有,您可以根据需要将其更改为延迟加载图像,或者至少将它们加载到后台线程中,以便调用者在加载时不会阻塞。

我还建议300k似乎有点大“缩略图”(代码表明它们是)。您是否正在根据您的实际需要调整它?