Microsoft apresenta versão 11 do Visual Studio

Deixe um comentário

A cada lançamento do Visual Studio, normalmente são apresentadas novas características tanto no seu IDE, quanto no suporte de linguagens de programação. O vice-presidente da divisão de desenvolvimento da Microsoft apresentou recentemente quais as mudanças que vão entrar no Visual Studio 11.

A nova versão dará pleno reconhecimento à linguagem JavaScript, assim como faz com as linguagens C#, Visual Basic e C++. As melhorias para JavaScript também incluem suporte para a linguagem ECMAScript 5 como padrão, e o suporte para remover bugs para JavaScript agora coincide com o que está previsto outras linguagens do Visual Studio, incluindo janelas de remover bugs que suportam interagir com o aplicativo que está sendo debugado. Talvez, a novidade mais interessante seja a adição de um REPL (Read-Evaluate-Print Loop) para o desenvolvimento JavaScript.

O suporte de programação assíncrona serão integrados ao C # 5 e ao Visual Basic 11. O uso de código assíncrono em versões anteriores do Visual Studio foi difícil de se implementar e debugar. No Visual Studio 11, ambas as áreas serão melhoradas, fornecendo novos recursos de linguagem que permitem o uso de fluxos de controle tradicionais (loops, condicionais etc) com código assíncrono e inclui a capacidade de debugar essas declarações com o removedor de bugs integrado.

O desenvolvimento com C++ deve receber diversas melhorias notáveis na nova versão, como, por exemplo, melhor suporte IDE e a capacidade de construir aplicativos nativos do Windows Metro. Há uma maior ênfase no suporte para escrever o código paralelo utilizando o C++ e a tecnologia AMP (Accelerated Massive Parallelism). O Visual Studio 11 permite debugar diretamente os aplicativos usando o C++ e a AMP.

A nova versão do Visual Studio vai introduzir o F# 3.0 e a funcionalidade Type Provider. Esse mecanismo tem evoluído em resposta à necessidade de ligar linguagens estaticamente tipadas (F #) para os dados cada vez mais dinâmicos encontrados na web. O F# 3.0 terá suporte para Odata, WSDL e SQL, mas provedores customizados podem ser escritos.

Fonte: iMasters

Links relacionados:

Anúncios

Service Pack do Visual Studio 2010

Deixe um comentário

A versão final do Service Pack 1 do Visual Studio 2010 está disponível para download.

Este service pack resolve problemas que foram encontrados através de uma combinação de clientes e de parceiros Microsoft, bem como testes internos. Este pacote oferece aos usuários do Visual Studio melhorias na estabilidade, agilidade e desempenho. O feedback recebido durante o lançamento da versão beta será utilizado para entregar uma versão final do service pack.

Fonte: Microsoft

A descrição completa das funcionalidades disponíveis neste service pack, bem como os problemas resolvidos, podem ser encontrados neste artigo.

Para fazer o download do Service Pack 1 do Visual Studio 2010, acesse este link.

Sincronização de Threads em C# e VB.NET

1 Comentário

Aviso: Boa parte do conteúdo deste artigo é uma tradução de artigo “Thread Synchronization (C# and Visual Basic)” disponibilizado pela Microsoft, que pode ser encontrado aqui.

Um dos benefícios do uso de múltiplas threads em uma aplicação é que cada uma delas é executado de forma assíncrona. Em aplicações desktop, isto permite que tarefas que consomem muito tempo possam ser executadas em segundo plano enquanto a janela do aplicativo e os controles continuam respondendo. Para aplicações em servidores, múltiplas tarefas fornecem a capacidade de lidar com cada solicitação de entrada com uma thread diferente, caso contrário, cada novo pedido não será atendido até que o pedido anterior tenha completado.

No entanto, a natureza assíncrona de threads significa que o acesso a recursos compartilhados, como arquivos, conexões de rede e memória devem ser sincronizados. Caso contrário, duas ou mais threads podem acessar o mesmo recurso ao mesmo tempo, e cada um desconhece a atuação da outra ação e o resultado é a corrupção de dados imprevisível e possíveis deadlocks.

Há algum tempo, fiz outros artigos que demonstram o uso de threads em C# e Visual Basic. Você pode encontrá-los aqui:

Lock e SyncLock

O Lock (C#) e o SyncLock (VB.NET) são declarações que podem ser utilizadas para garantir que um bloco de código seja executado até sua conclusão, prevenindo a interrupção da execução por outras threads. Essas declarações são interpretadas pelo compilador como bloqueios para um determinado objeto em um bloco de códigos. Se outra thread tenta executar o código envolvido pelo lock / SyncLock, ela esperará até que a primeira thread termine a execução e libere o objeto / código bloqueado.

//C#
public class LockTest
{
    public void TestarLock()
    {
        lock (this)
        {
            // Código que estará protegido pelo lock.
        }
    }
}
'VB.NET
Public Class LockTest
    Public Sub TestarLock()
        SyncLock Me
            ' Código que estará protegido pelo lock.
        End SyncLock
    End Sub
End Class

Sincronização de Eventos e Wait Handles

Existem dois tipos de sincronização: AutoResetEvent e ManualResetEvent. Eles diferem apenas na medida em que as mudanças são setadas automaticamento no AutoResetEvent e manualmente no ManualResetEvent. O ManualResetEvent permite que qualquer número de threads possa ser alinhado e ter seu estado atualizado.

Métodos são usados para esperar a execução de um ou mais threads. Esses métodos indicam ao compilador quando e quantas threads devem ter o processamento concluído para que o fluxo continue. São eles: WaitOne, WaitAny e WaitAll. WaitOne faz com que o compilador espere a execução de um único thread estar concluída. WaitAny faz o compilador aguardar a execução dos métodos indicados. WaitAll bloqueia a execução até que todas as threads estejam concluídas. Para sinalizar a conclusão da execução de uma thread usa-se o método Set.

// C#
namespace GerenciaSincronizacao
{
    public class GerenciarThreads
    {
        private ManualResetEvent[] manualResetEvent;

        private void ExecutarThread0(object obj)
        {
            Thread.Sleep(20000);
            Console.WriteLine("Thread 0 concluída!");
            manualResetEvent[0].Set();
        }

        private void ExecutarThread1(object obj)
        {
            Thread.Sleep(13000);
            Console.WriteLine("Thread 1 concluída!");
            manualResetEvent[1].Set();
        }

        private void ExecutarThread2(object obj)
        {
            Thread.Sleep(9000);
            Console.WriteLine("Thread 2 concluída!");
            manualResetEvent[2].Set();
        }

        private void ExecutarThread3(object obj)
        {
            Thread.Sleep(17000);
            Console.WriteLine("Thread 3 concluída!");
            manualResetEvent[3].Set();
        }

        public void Executar()
        {
            manualResetEvent = new ManualResetEvent[4];

            manualResetEvent[0] = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(this.ExecutarThread0);

            manualResetEvent[1] = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(this.ExecutarThread1);

            manualResetEvent[2] = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(this.ExecutarThread2);

            manualResetEvent[3] = new ManualResetEvent(false);
            ThreadPool.QueueUserWorkItem(this.ExecutarThread3);

            WaitHandle.WaitAll(manualResetEvent);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            GerenciarThreads gt = new GerenciarThreads();
            gt.Executar();

            Console.WriteLine("Pressione ENTER para terminar.");
            Console.ReadKey();
        }
    }
}
' VB.NET
Namespace GerenciaSincronizacao
    Public Class GerenciarThreads
        Private manualResetEvent As ManualResetEvent()

        Private Sub ExecutarThread0(obj As Object)
            Thread.Sleep(20000)
            Console.WriteLine("Thread 0 concluída!")
            manualResetEvent(0).[Set]()
        End Sub

        Private Sub ExecutarThread1(obj As Object)
            Thread.Sleep(13000)
            Console.WriteLine("Thread 1 concluída!")
            manualResetEvent(1).[Set]()
        End Sub

        Private Sub ExecutarThread2(obj As Object)
            Thread.Sleep(9000)
            Console.WriteLine("Thread 2 concluída!")
            manualResetEvent(2).[Set]()
        End Sub

        Private Sub ExecutarThread3(obj As Object)
            Thread.Sleep(17000)
            Console.WriteLine("Thread 3 concluída!")
            manualResetEvent(3).[Set]()
        End Sub

        Public Sub Executar()
            manualResetEvent = New ManualResetEvent(3) {}

            manualResetEvent(0) = New ManualResetEvent(False)
            ThreadPool.QueueUserWorkItem(AddressOf Me.ExecutarThread0)

            manualResetEvent(1) = New ManualResetEvent(False)
            ThreadPool.QueueUserWorkItem(AddressOf Me.ExecutarThread1)

            manualResetEvent(2) = New ManualResetEvent(False)
            ThreadPool.QueueUserWorkItem(AddressOf Me.ExecutarThread2)

            manualResetEvent(3) = New ManualResetEvent(False)
            ThreadPool.QueueUserWorkItem(AddressOf Me.ExecutarThread3)

            WaitHandle.WaitAll(manualResetEvent)
        End Sub
    End Class

    Class Program
        Private Shared Sub Main(args As String())
            Dim gt As New GerenciarThreads()
            gt.Executar()

            Console.WriteLine("Pressione ENTER para terminar.")
            Console.ReadKey()
        End Sub
    End Class
End Namespace

A classe Interlocked

Você pode usar os métodos da classe Interlocked para evitar problemas que podem ocorrer quando várias threads tentam simultaneamente atualizar ou comparar um mesmo valor. Os métodos dessa classe permitem que você assegure o incremento, decremento, troca e comparação entre valores em qualquer thread.

As operações mais utilizadas desta classe são:

  • O método Add adiciona um valor inteiro para uma variável e retorna o novo valor da variável.
  • O método Read lê um valor inteiro de 64 bits.
  • Os métodos Increment e Decrement são utilizados para incrementar ou decrementar valores em uma variável e retornam o valor resultante.

O código a seguir demonstra o uso do Increment.

// C#
private static ManualResetEvent[] manualResetEvents;

public void Teste()
{
    int intQuantidadeInteracoes = 10;
    int intContador = 0;

    manualResetEvents = new ManualResetEvent[intQuantidadeInteracoes];

    for (int i = 0; i < intQuantidadeInteracoes; i++)
    {
        manualResetEvents[intContador] = new ManualResetEvent(false);

        ThreadPool.QueueUserWorkItem(this.Executar, intContador);

        Interlocked.Increment(ref intContador);
    }

    WaitHandle.WaitAll(manualResetEvents);
}

public void Executar(object intContador)
{
    Console.WriteLine("Posição atual do contador: {0}",
        Convert.ToInt32(intContador));

    manualResetEvents[Convert.ToInt32(intContador)].Set();
}
' VB.NET
Private Shared manualResetEvents As ManualResetEvent()

Public Sub Teste()
    Dim intQuantidadeInteracoes As Integer = 10
    Dim intContador As Integer = 0

    manualResetEvents = New ManualResetEvent(intQuantidadeInteracoes - 1) {}

    For i As Integer = 0 To intQuantidadeInteracoes - 1
        manualResetEvents(intContador) = New ManualResetEvent(False)

        ThreadPool.QueueUserWorkItem(AddressOf Me.Executar, intContador)

        Interlocked.Increment(intContador)
    Next

    WaitHandle.WaitAll(manualResetEvents)
End Sub

Public Sub Executar(intContador As Object)
    Console.WriteLine("Posição atual do contador: {0}", Convert.ToInt32(intContador))

    manualResetEvents(Convert.ToInt32(intContador)).[Set]()
End Sub

Referências

Extension Methods no C#

5 comentários

Apesar de ser um assunto de certa forma “esgotado”, que muitos estão cansados de saber, resolvi escrever este post, pois acho uma opção interessante para os desenvolvedores da plataforma .net.

Os métodos de extensão surgiram junto com o .Net Framework 3.5, e permitem adicionarmos novas funcionalidades a tipos existentes, sem a necessidade de alterar o tipo original e recompilá-lo. Devem sempre ser métodos estáticos, mas a chamada para eles é muito parecida com a chamada para métodos de instância. O primeiro parâmetro especifica em qual o tipo que método opera e deve sempre ser seguido da palavra chave this.

A classe que conterá o método de extensão, assim como o próprio método, também deve ser estática e a Namespace deve ser declarada nos locais onde o método de extensão deverá ficar disponível, através de using.

OBS: Todos os códigos contidos neste artigo estão em Linguagem C#

Vejamos um exemplo de criação método de extensão:

// C#
public static class MetodosDeExtensao
{
    /// <summary>
    /// Verifica se um objeto é nulo
    /// </summary>
    /// <param name="obj">object, objeto a ser verificado</param>
    /// <returns>bool, true quando o objeto for nulo</returns>
    public static bool IsNull(this object obj)
    {
        if (obj == null)
            return true;
        else
            return false;
    }
}

No exemplo acima, fizemos um método de extensão que verifica se um objeto é nulo ou não. É possível ver a palavra chave this antes a declaração do primeiro parâmetro do método, que é o identificador do tipo onde o método de extensão será aplicado.

O método em sí, terá a mesma estrutura de qualquer outro método estático, ou seja, não muda nada na forma de desenvolvimento e poderá ser usado normalmente como um método estático. Veja:

// C#
// utilizando a maneira convencional
string strNome = "Fernando Ottoboni";
if (MetodosDeExtensao.IsNull(strNome))
    Console.WriteLine("Nome não informado.");

Mas já que estamos falando de métodos de extensão, vamos então ver a forma correta de utilização do mesmo.

A partir do momento que o método de extensão foi criado, em todos os locais onde a namespace estiver acessível (lembre-se do using), o tipo declarado no método passará a conter uma nova extensão. Veja:

A seguir é possível ver um exemplo da sintaxe completa de utilização do nosso método de extensão.

// C#
// utilizando o método de extensão
string strNome = "Fernando Ottoboni";
if (strNome.IsNull())
    Console.WriteLine("Nome não informado.");

Em algumas situações, precisamos fazer métodos que devem ter dois ou mais parâmetros de entrada. Isso também é possível em métodos de extensão, mas devemos lembrar que sempre precisamos colocar o this no primeiro parâmetro (sempre no primeiro e somente nele). Os parâmetros restantes serão parâmetros comuns. Vejamos um exemplo:

// C#
/// <summary>
/// Completa a string com a quantidade e o caracter informado
/// </summary>
/// <param name="str">String, string a ser completada</param>
/// <param name="caracter">String, caracter a ser usado ao completar</param>
/// <param name="qt">Int, quantidade de caracteres</param>
/// <returns>String, string completada com os caracters</returns>
public static string CompletarString(this string str, string caracter, int qt)
{
    if (string.IsNullOrEmpty(str))
        str = "";

    if (caracter.Length > 1)
        caracter = caracter.Substring(0, 1);

    StringBuilder stb = new StringBuilder();

    if (string.IsNullOrEmpty(caracter.ToString()))
        caracter = " ";

    if (qt - str.Length > 0)
    {
        qt = qt - str.Length;
        stb.Append(str);
        stb.Append(new String(Convert.ToChar(caracter), qt));
    }
    else
    {
        stb.Append(str.Substring(0, qt));
    }

    return stb.ToString();
}

Existem várias outras situações e cenários onde podemos usar métodos de extensão. Vejamos então alguns lugares interessantes:

  • IsNullOrEmpty

Adquiri tão rapidamente o costume de usar métodos de extensão, que tive que fazer tornar o IsNullOrEmpty (String.IsNullOrEmpty) um deles apenas por conveniência.

// C#
/// <summary>Verficar se uma string é nula ou vazia</summary>
public static bool IsNullOrEmpty(this string str)
{
    return string.IsNullOrEmpty(str);
}
  • IsNullOrWhiteSpace

Assim como os IsNullOrEmpty, o mesmo pode ser feito com o IsNullOrWhiteSpace (String.IsNullOrWhiteSpace).

// C#
/// <summary>
/// Verficar se uma string é nula ou espaço em branco
/// </summary>
public static bool IsNullOrWhiteSpace(this string str)
{
    return string.IsNullOrWhiteSpace(str);
}
  • IsDateTime

Verificar se um string é um DateTime válido.

// C#
/// <summary>
/// Verificar se o conteúdo da string equivale a um DateTime
/// </summary>
public static bool IsDateTime(this string str)
{
    string strData = str;

    if (string.IsNullOrEmpty(strData))
        return false;

    try
    {
        DateTime datData = Convert.ToDateTime(strData);
        return true;
    }
    catch
    {
        return false;
    }
}
  • IsDecimal

Verificar se um string é um Decimal válido.

// C#
/// <summary>
/// Verificar se o conteúdo da string equivale a um decimal.
/// </summary>
public static bool IsDecimal(this string str)
{
    if (String.IsNullOrEmpty(str))
        return false;

    try
    {
        Convert.ToDecimal(str);
        return true;
    }
    catch
    {
        return false;
    }
}
  • ReverseString

Retorna a string reversa.

// C#
/// <summary>
/// Retorna a string de forma reversa
/// </summary>
/// <param name="str">String a ser revertida</param>
/// <returns>String revertida</returns>
public static string ReverseString(this string str)
{
    char[] arr = str.ToCharArray();
    Array.Reverse(arr);
    return new string(arr);
}
  • Left

Extrai um Substring do lado esquerdo da string conforme a quantidade de caracteres desejada.

// C#
/// <summary>
/// Extrai um Substring do lado esquerdo da string
/// conforme a quantidade de caracteres desejada
/// </summary>
/// <param name="str">String para extrair o substring</param>
/// <param name="length">Quantidade de caracteres a extrair</param>
/// <returns>String</returns>
public static string Left(this string str, int length)
{
    if (str.IsNullOrEmpty())
        return str;

    if (str.Length <= length)
        return str;

    return str.Substring(0, length);
}
  • Right

Extrai um Substring do lado direito da string conforme a quantidade de caracteres desejada.

OBS: Usa o método ReverseString.

// C#
/// <summary>
/// Extrai um Substring do lado direito da string conforme a quantidade de caracteres desejada
/// </summary>
/// <param name="str">String para extrair o substring</param>
/// <param name="length">Quantidade de caracteres a extrair</param>
/// <returns>String</returns>
public static string Right(this string str, int length)
{
    if (str.IsNullOrEmpty())
        return str;

    if (str.Length <= length)
        return str;

    return str.ReverseString().Substring(0, length).ReverseString();
}

Existem muitas outras possibilidades, e no código fonte que pode ser baixado logo abaixo coloquei alguns outros exemplos.

LINQ e os Métodos de Extensão

Há algum tempo, fiz um artigo que mostrei como utilizar e como funcionam os métodos de extensão disponíveis para utilização com LINQ. Se quiser conferir, basta clicar aqui.

Códigos fontes

Os códigos-fontes deste artigo podem ser baixados aqui.

Referências

Por que usar StringBuilder?

2 comentários

Outro dia fiz um post que mostra a comparação entre String e StringBuilder com relação a velocidade de execução. A intuito deste novo post é explicar o por que do StringBuilder levar muito menos tempo na execução do que os Strings comuns. [Dica do 1000TON – Valeu cara!]

O que o Milton disse no comentário dele foi:

Realmente a diferença é brutal. A forma de trabalho das strings faz com que a mesma seja mais lerda, isso pq sempre que concatenamos o compilador gera um novo array de char com o tamanho final (antigo + tamanho concatenado)

…..

Vamos as explicações

Toda vez que o conteúdo de uma string é alterado, um novo objeto string é criado na memória, o que requer uma nova alocação de espaço para esse novo objeto. Em situações onde é necessários realizar repetidas modificações em uma string (como o caso do exemplo que dei no meu post), a sobrecarga associada à criação de um novo string pode ter um custo caro, tanto em tempo de execução, quanto em uso de memória. O StringBuilder pode ser usado para esses casos de necessidade de modificar strings sem criar um novo objeto.

O StringBuilder representa uma sequência de caracteres cujo valor pode ser modificado. Dizer que o valor pode ser modificado significa que pode ser alterado depois de ter sido criado, acrescentando, removendo ou substituindo caracters.

O desempenho de uma operação de concatenação de um String ou StringBuilder depende da freqüência na qual a alocação de memória ocorre. Como já disse, um string sempre aloca memória a cada concatenação (alteração). Já com o StringBuilder, a operação de concatenação aloca memória apenas para os novos conteúdos adicionados. Consequentemente, string é preferível para operações de concatenação com um número fixo de objetos a serem concatenados. Nesse caso, as operações de concatenação são combinadas em uma única operação pelo compilador.  Já o StringBuilder é preferível para uma operação de concatenação quando um número grande de concatenações devem ser realizadas.

Membros importantes do StringBuilder

  • Construtor StringBuilder(): Inicializa uma nova instância da classe StringBuilder.
  • Método Append(): Concatena um novo objeto à instância do StringBuilder. Existem vários overloads deste métodos, na qual vários tipos de dados podem ser usados, como Boolean, Int, Decimal, String, etc., não necessariamente strings.
  • Método AppendLine(): Concatena um novo objeto à instância do StringBuilder e adiciona um terminador de linha ao final da concatenação.
  • Método Clear(): Limpa o StringBuilder.
  • Método Insert(): Insere o conteúdo especificado na posição desejada.
  • Método Remove(): Remove o intervalo especificado de caracteres da instância do StringBuilder.
  • Método Replace(): Substitui todas as ocorrências de um caractere especificado com outro caractere especificado.
  • Método ToString(): Converte o conteúdo do StringBuilder para uma string comum.
  • Propriedade Capacity: Obtém ou define a quantidade máxima de caracteres que podem ser contidos na memória alocada pela instância do StringBuilder.
  • Propriedade Length: Obtém o comprimento da instância atual do StringBuilder.

Fontes

Visual Studio 2010 SP1 Beta

2 comentários

O Service Pack 1 Beta do Visual Studio 2010 já está disponível para download.

Este service pack beta resolve problemas que foram encontrados através de uma combinação de clientes e de parceiros Microsoft, bem como testes internos. Este pacote oferece aos usuários do Visual Studio melhorias na estabilidade, agilidade e desempenho. O feedback recebido durante o lançamento da versão beta será utilizado para entregar uma versão final do service pack.

Fonte: Microsoft

O Downlod pode ser feito através deste link.

Fonte: Jason Zander’s WebLog

String Vs. StringBuilder

6 comentários

Você concatena strings com concatenação comum ou usa o StringBuilder?

Há alguns dias fui questionado sobre isso e na hora me veio a idéia de fazer um teste para comparação.

Conceitos

StringBuilder: http://msdn.microsoft.com/en-us/library/2839d5h5(v=VS.100).aspx

String: http://msdn.microsoft.com/en-us/library/362314fe(v=VS.100).aspx

Vamos ao Teste

Fiz um pequeno programa que simula uma grande quantidade de concatenações ou appends em StringBuilders. A idéia é um bloco for que concatena uma string várias vezes e outro bloco for que faz vários appends em um StringBuilder. Algo desse tipo:

// Várias concatenações na string
string str = string.Empty;
for (int i = 1; i <= qt; i++)
    str = str + " Concatenação nº " + i.ToString();

// Vários appends no StringBuilder
StringBuilder stb = new StringBuilder();
for (int i = 1; i <= qt; i++)
{
    stb.Append(" Append nº ");
    stb.Append(i.ToString());
}

O resultado foi de impressionar. Veja:

No teste, executei 100.000 concatenações/appends, e o tempo de execução das concatenações foi absurdamente maior que o tempo de execução dos appends.

Portanto, a partir de agora, use StringBuilder em vez de strings comuns.

O código fonte pode ser baixado aqui.

Valeu galera!

Older Entries