This is a mirror of official site: http://jasper-net.blogspot.com/

WebRTC #1 — Знакомимся

| Wednesday, December 26, 2012
Многие уже слышали о проекте WebRTC, некоторые даже используют его (или пытаются применять в существующих проектах), а кто-то злобно потирает руки, предвкушая постепенную расправу со Skype и Flash.

Погуглив в Хабре (хе-хе) я почему-то не нашел статей, которые углублялись в техническую сторону WebRTC, показывали бы примеры его использования.

Что же, я попытаюсь порадовать вас схемками, кодом. В общем, именно тем, что всем по вкусу. Так пройдем же под кат, мой любимый читатель.

Что это?

WebRTC — проект, который позволяет получать медиаданные (аудио и видео) через браузер и устанавливать Peer-to-Peer соединение между двумя и более клиентами, через которое могут передаваться обычные данные и медиапотоки.

По сути, WebRTC являет собой:
1. Media Streams (getUserMedia).
2. Peer Connection.

Ниже я вкратце опишу эти элементы, но подробное описание я все же хочу оставить на две следующие части статьи.

Media Streams

Media Streams — API, позволяющий получить доступ к камере и микрофону через браузер без каких-либо плагинов и флеша.

Следуя WebRTC Public API, нам нужно использовать метод getUserMedia у глобального объекта navigator.
Передавать стоит три параметра:
— объект со списком того, что нам нужно (аудио/видео)
— success callback
— error callback

И пока что есть необходимость в костылях из-за наличия префиксов в различных браузерах:

var getUserMedia;
    
var getUserMedia;
var browserUserMedia = navigator.webkitGetUserMedia || // WebKit
                        navigator.mozGetUserMedia || // Mozilla FireFox
                        navigator.getUserMedia; // 2013...
if ( !browserUserMedia ) throw 'Your browser doesn\'t support WebRTC';

getUserMedia = browserUserMedia.bind( navigator );

getUserMedia(
    {
        audio: true,
        video: true
    },
    function( stream ) {
        console.log( stream );
    },
    function( err ) {
        console.log( err );
    }
);

Read more: Habrahabr.ru
QR: Inline image 1

Posted via email from Jasper-net

Многоядерная JIT-компиляция в .NET 4.5

|
Исторически разработчики .NET использовали генератор образов в машинном коде Ngen. Это отлично работает, если у вас есть инсталлятор, и вы можете сгенерировать эти образы во время установки приложения. Но в других случаях, например когда у вас нет установщика или вы не имеете доступ к Ngen, ваше приложение будет производить JIT-компиляцию по мере необходимости, что замедлит его загрузку. Разработчики CLR предоставили решение в новой версии .NET – многоядерная JIT-компиляция с возможностью создавать профили оптимизации.

При многоядерной JIT-компиляции код компилируется на двух ядрах параллельно. Чем больше кода вы выполняете во время загрузки, тем более заметным будет ускорение от многоядерного JIT. Вы можете получить уменьшение времени загрузки на 20-50%, что является хорошей новостью для тех, кто разрабатывает большие приложения и не имеют возможности использовать Ngen. Для этого потребуется добавить в ваш код всего пару строчек кода.

Как это работает

В общем случае вам понадобится вызвать всего два метода в своём приложении:
Указать место, где будут храниться профили многоядерного JIT,
И начать профайлинг, вызвав метод StartProfile.

.NET runtime создаст профиль исходя из последовательностей вызванных методов во время работы вашего приложения. Этот профиль будет сохранён на диск. Проще говоря, при первом запуске произойдёт «запись» профиля (картинки взяты отсюда):

Inline image 1

...
...

Используем многоядерную JIT-компиляцию

Использовать многоядерную JIT-компиляцию просто. В .NET 4.5 присутствует класс System.Runtime.ProfileOptimization, который мы можем использовать для того, чтобы начать запись профиля во время старта приложения. Этот код выглядит примерно так:

ProfileOptimization.SetProfileRoot(@"C:\MyApp");
ProfileOptimization.StartProfile("LaunchProfile");

SetProfileRoot — включает оптимизацию для текущего AppDomain и устанавливает директорию, куда будет сохраняться профиль оптимизации. Этот метод игнорируется на одноядерных комрьютерах.

StartProfile – начинает профайлинг и just-in-time компиляцию для тех методов, которые были записаны в профиль (если он уже есть).

Read more: Habrahabr.ru
QR: Inline image 2

Posted via email from Jasper-net

Как стать кукловодом или Puppet для начинающих

|
Что такое система управления конфигурацией?

Предположим, что у вас есть парк серверов, выполняющих различные задачи. Пока серверов мало и вы не растёте, вы легко настраиваете каждый сервер вручную. Устанавливаете ОС (может быть, автоматизированно), добавляете пользователей, устанавливаете софт, вводя команды в консоль, настраиваете сервисы, правите конфиги ваших любимых текстовых редакторов (nanorc, vimrc), выставляете на них одинаковые настройки DNS-сервера, устанавливаете агент системы мониторинга, настраиваете syslog для централизованного сбора логов… Словом, работы довольно много и она не особенно интересна.

Я искренне верю, что хороший админ — ленивый админ. Он не любит делать что-то несколько раз. Первая мысль — написать пару скриптов, в котором будет что-то наподобие:

servers.sh
servers="server00 server01 server02 server03 server04"

for server in $servers ; do
  scp /path/to/job/file/job.sh $server:/tmp/job.sh
  ssh $server sh /tmp/job.sh
done

job.sh
#!/bin/bash
apt-get update
apt-get install nginx
service nginx start

Вроде всё стало легко и хорошо. Нужно что-то сделать — пишем новый скрипт, запускаем. Изменения приходят на все серверы последовательно. Если скрипт хорошо отлажен — всё станет хорошо. До поры.

Теперь представьте, что серверов стало больше. Например, сотня. А изменение долгое — например, сборка чего-нибудь большого и страшного (например, ядра) из исходников. Скрипт будет выполняться сто лет, но это полбеды.

Представьте, что вам нужно сделать это только на определенной группе из этой сотни серверов. А через два дня нужно сделать другую большую задачу на другом срезе серверов. Вам придётся каждый раз переписывать скрипты и много раз проверять, нет ли в них каких-нибудь ошибок, не вызовет ли это какой-нибудь проблемы при запуске.

Самое плохое — это то, что в подобных скриптах вы описываете действия, которые необходимо выполнить для приведения системы в определенное состояние, а не само это состояние. Значит, если система изначально находилась не в том состоянии, что вы предполагали, то всё обязательно пойдет не так. Манифесты Puppet декларативно описывают необходимое состояние системы, а вычисление, как к нему прийти из текущего состояния — задача самой системы управления конфигурацией.

Для сравнения: манифест puppet, выполняющий ту же работу, что и пара скриптов из начала топика:

nginx.pp
class nginx {
  package { 'nginx':
    ensure => latest
  }
  service { 'nginx':
    ensure => running,
    enable => true,
    require => Package['nginx']
  }
}
node /^server(\d+)$/ {
  include nginx
}

Если правильно использовать серверы и потратить некоторое время на первичную настройку системы управления конфигурацией, можно добиться такого состояния парка серверов, что вам не потребуется логиниться на них для выполнения работы. Все необходимые изменения будут приходить к ним автоматически.

Read more: Habrahabr.ru
QR: Inline image 1

Posted via email from Jasper-net

ZeroMQ via C#: Multi-part messages, JSON and Synchronized PUB-SUB pattern

|
Introduction  

This is the second part of the ZeroMQ via C#. Other parts are:  

ZeroMQ via C#: Introduction 

In this article we will talk about the two types of messages that ZeroMQ can send or receive and how to format these messages using JSON. We will also learn the polling mechanism and how to use it. Finally, we will explore the synchronized PUB-SUB pattern with an example.   

ZeroMQ messages  

ZeroMQ sockets can send or receive either a single-part or a multi-part message.

Single-part Message 

A single-part message is a message that has one frame. A frame is an array of bytes. The length of a frame can be zero upwards. Frames also called "message parts" in ZeroMQ reference manual. 

For example, the messages that we sent/received in the previous article were all single-part messages type. We have used strings during sending receiving operations (a string is an array of bytes). 

We can use the following methods (found in clrzmq.dll library) to send or receive a single-part message (single-frame message):  

Send\Receive 
SendFrame\ReceiveFrame 

Multi-part Messages 

A multi-part message is a message that has more than one frame. ZeroMQ sends this message as a single on-the-wire message and guarantees to deliver all the message parts (one or more), or none of them. 

Inline image 2

Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net

Xamarin is Bringing C# to the Mac App Store

| Monday, December 24, 2012
Xamarin, makers of the popular MonoTouch and Mono for Android platforms, have entered into the Mac App Store market with Xamarin.Mac.

This isn’t the first someone tried to create C# bindings for OS X. Previous attempts include Cocoa Sharp, Monobjc, and NObjective. Part of what makes this attempt different is that it is a commercial offering, Xamarin has a financial stake in not allowing the bindings to become obsolete.

You may notice that MonoMac is missing from the above list. That’s because Xamarin.Mac is an extension to MonoMac. In addition to removing the LGPL licensing restrictions, Xamarin.Mac offers a few advantages over MonoMac.

Most importantly, it creates fully self-contained applications. Users will not need to install Mono separately, which is a requirement for the Mac App Store and a convenience for everyone else.

Xamarin.Mac also includes support for frameworks that MonoMac overlooked.

  • CoreBluetooth
  • GameKit
  • New MountainLion AppKit APIs
  • SceneKit
  • StoreKit
Xamarin.Mac is currently targeting MacOS X Lion and Moutain Lion. Xamarin also recommends developers use the most recent version of Xcode, currently 4.5.2.

While Xamarin.Mac will allow developers to share business logic between the various platforms, anything that touches the UI will need to be rewritten for the Mac. Rather than offering a cross-platform toolkit, Xamarin is encouraging developers to use native bindings to ensure the applications look right on each device.

For many developers, this has been a long time point of contention. They would rather have a XAML-based UI language, possibly based on Silverlight/Moonlight, that offers a “write-once, run-anywhere” experience. Some have even expressed interest in XAML even if it isn’t reusable across platforms because of rich support for styling and animations.

When asked, adamkemp of Data Dashboard had this to say about the topic of code reuse,

I am one of the lead developers for Data Dashboard for iPad, which is the first case study app mentioned in the announcement. We got quite a bit of code reuse from C# code written for WPF/Silverlight. The UI parts or totally different, but there's a lot of non-UI code in a large app.

Read more: InfoQ
QR: Inline image 1

Posted via email from Jasper-net

Attached Behaviors vs Attached Properties vs Blend Behaviors

|
Brian Lagunas asked a very good question based on seeing my sample video from my Pluralsight Windows 8 MVVM XAML Apps course, the gist of which was (paraphrased): “Why do you call them Attached Behaviors – won’t that cause confusion with what is an Attached Property and with Blend Behaviors?”

My initial answer was along the lines of “because that is what we called them back in the day, long before Blend picked up the concept and created their own behaviors.”

But Brian rightly pointed out that not everyone has as deep of history working with XAML as I do and a lot of people only associated the term behavior with Blend Behaviors. He also asked how to discriminate a simple attached property from an attached behavior.

Here is my response:

I think the distinction in my mind is this: "normal" attached properties are there as metadata for some other piece of code (i.e. a container control like a Grid or a ToolTip) to modify its own behavior based on the presence of that attached property. When used like that, attached properties are like attributes in C# or VB code - they don't do any work themselves, they are just there to influence behavior implemented somewhere else.

When an attached property has a change handler that acts on the exposed API of the DependencyObject to which it is attached, it is an attached behavior - in which case it is much more like an extension method in C# - a chunk of code that can be associated with that object to supplement that object's behavior or functionality without that object's knowledge.

A similar discussion also recently came up while working with the Microsoft patterns & practices Kona team on Line-Of-Business guidance for Windows 8. As a result of that discussion, I wrote up a couple page summary with some snippets to compare and contrast Attached vs Blend Behaviors. So I’m including that content here as well.

Attached and Blend Behaviors

Behaviors are a way of supplementing the functionality, or behavior, of XAML elements. A behavior is a chunk of code you write that can be used in XAML by attaching it to some element through attached properties. The behavior can use the exposed API of the element to which it is attached to add functionality to that element or other elements in the visual tree of the view. In this way, they are the XAML equivalent of C# extension methods. Extension methods allow you to define additional methods for some class in C# without modifying the class definition itself, and they work against the exposed API of the class. Behaviors allow you to add functionality to an element by writing that functionality in the behavior class and attaching it to the element as if it was part of the element itself.

Ultimately behaviors package up code that you would normally have to write as code behind because it directly interacts with the API of XAML elements in a way that it can be concisely hooked up to an element in the XAML and packaged for reuse across more than one view or application. They can be used to encapsulate a complex coding pattern of interaction for a given control, do visual tree walks to discover and hook things up throughout a view, and virtually any scenario where you ask yourself “how do I do XYZ?” and the answer is “you write this code behind”. In the context of MVVM, they are a great way to bridge from things that are happening in the view due to user interaction and getting the information and execution into a view model. So you can hook events and properties from a given control type and feed those down into a view model in a standardized fashion.

Read more: Brian Noyes blog
QR: Inline image 1

Posted via email from Jasper-net

Profiling Code – The Microsoft Way

|
Inline image 2

A colleague of mine asked me how he can find out why his laptop does consume 30% CPU in the SYSTEM process after it did wake up from hibernate. That is easy I replied: Open Process Explorer select the SYSTEM process, double click it, select the thread tab, sort by CPU and double click on the first thread which does consume so much CPU to get the call stack.

A few days later I got a mail back that it did not work. Ok could be some elevation problem. I did try it on my machine and sure enough access denied also here. Ups it is not so easy after all. A little googling around did lead to a very good article from Mark Russinovich dealing with the exact same issue. Mark did use Kernrate which seems to work still on Windows 7 but it does look rather unsupported. A few other articles indicated that xperf should also be able to do it. So I did look where to get the latest edition of XPerf. It turns out that it is part of the Windows 8 SDK and the Windows Assessment and Deployment Kit (ADK) für Windows® 8. You do not need to download GBs of stuff. Only select the Windows Performance Toolkit and uncheck all other stuff. That gives you a nice ~50MB download which will install it to

%PROGRAMFILES(X86)%\Windows Kits\8.0\Windows Performance Toolkit

Besides the well known Xperf tool I have written several years ago some new stuff was added. Recording performance with the latest version of the Windows Performance Toolkit has never been so easy. There is a tool called WPRUI.exe which allows you to record a trace session with a nice GUI. An interesting side note is that this tool is missing in the Windows 8 SDK delivered with Visual Studio 2012. If you download the latest version again you get the GUI tool as well. It does seem to have full support from MS and they did even localize the UI which is rather unusual for such low level tools.

Read more: Alois Kraus
QR: Inline image 1

Posted via email from Jasper-net

WCF – Custom Message Encoder and Operation Message Size

|
You may find the need to determine the request and reply message size when calling a service operation. 
It can be for logging purposes, or a practical one such as deciding whether you need to compress the data or not.

The key component in WCF that knows about the actual size of the message is the message encoder, and of course, you can plug-in your own encoder as part of WCF’s extensibility point. Ahhh, got to love this framework!

Lets examine the feature requirements first -

We need to have a way to get the incoming message size in our service implementation.
We need a way to enable the client to get the reply message size.
You can download the code here.

Basically, in order to implement a message encoder and to plug it in, you need to implement your own MessageEncoder, MessageEncoderFactory, and MessageEncodingBindingElement. 
Additionally, since this is part of the binding elements, we need to plug it in as part of the binding.

The implementation is fairly simple, since all I did was wrap the existing ones and added my message headers in the proper place. 
I will not show this code here, it’s pretty straight forward, I recommend you just download the code and take a look at it.

Finally, I implemented a behavior that you can attach to your service which does all the heavy lifting for you. 
It actually switches the current binding with a wrapper binding that plugs in our custom message encoder, pretty sweet.

In conclusion, here’s how our service would look like:

[OperationMessageSizeBehavior]
public class MyService : IMyService
{
    public void Do(Foo foo)
    {
        Console.WriteLine("MyService.Do() - Incoming request size: {0}KB",
            OperationMessageSizeExtension.Current.SizeInBytes / 1024);
    }
}

QR: Inline image 1

Posted via email from Jasper-net

Where I can find SQL generated by Linq-To-SQL

|
Yesterday I have written a blog post about Where I can find SQL Generated by Entity Framework? and same day I got request from one of the our reader Ramesh that how I can find SQL generated by Linq-To-SQL?. I thought its a good idea to write a blog post to share amongst all who need this instead of reply in comments.  In this post I am going to explain how we can get SQL generated by Linq-To-SQL.

For this post I am going to use same table like following. A customer table with two columns CustomerId and CustomerName.

...
...

using System;
using System.Linq;
using System.Data;
 
namespace LinqToSQL
{
    class Program
    {
        static void Main(string[] args)
        {
            using (CustomerDataContext customerContext = new CustomerDataContext())
            {
                var customerNames = from c in customerContext.Customers
                                    select c.CustomerName;
                string sql = customerContext.GetCommand(customerNames).CommandText;
 
                Console.WriteLine(sql);
            }
        }
    }
}

Now let’s run this console application to see SQL generated by Linq-To-SQL query and following is the output as expected.

Read more: DotNetJalps
QR: Inline image 1

Posted via email from Jasper-net

A new way to distribute your internal Android apps

|
Inline image 2

The Google Play Store is the place to find Android apps like the Google+ app, the Google Drive app and hundreds of thousands more. Today we’re expanding the Google Play Store for our Google Apps customers to help you distribute internal apps to your employees through the Google Play Private Channel. 

Whether you’ve built a custom expense reporting app for employees or a conference room finder, the Google Play Private Channel is designed to make your organization’s internal apps quick and easy for employees to find. Once your company has loaded these internal apps using the Google Play Developer Console, users just need to log in with their company email address to browse the Private Channel and download apps. 

These changes make it easier than ever to get the internal Android apps your company develops into employees’ hands. If you’re a Google Apps for Business, Education or Government customer you can learn more about how to create your organization’s own Google Play Private Channel in our Help Center.

QR: Inline image 1

Posted via email from Jasper-net

Linq to Collections: Beyond IEnumerable

|
The latest version of the .Net framework (4.5) includes several new interfaces representing readonly collections: IReadOnlyCollection<T>, IReadOnlyList<T>, and IReadOnlyDictionary<T>. In this post I’ll be explaining how to use these types to improve the ease-of-reasoning-about and efficiency (particularly with respect to memory usage).

The methods and types I’ll be describing are available as a software library (called “LinqToCollections”, in the public domain). You can view the library’s source code on GitHub or directly reference its NuGet package.

Motivation
Before I start talking about really taking advantage of the new readonly collection interfaces, I want to justify why it’s worth bothering with them in the first place. Why not just use the array or IList<T> types? Why not just use the more general IEnumerable<T> type? It’s worked in the past, so why not continue doing so?

First, it is better to ask for an IReadOnlyList<T>, as opposed to an IList<T> or an array, when you don’t need the ability to mutate. Doing so obeys the principle of asking only for what you need. If you don’t need the ability to mutate what you’re given, don’t ask for a thing with that ability. This increases the number of cases where your method can be used and makes reasoning about it easier. If you ask for an IReadOnlyList<T>, then a user (or automated tool) can trivially determine that their precious list won’t be mangled by your method. But, if you ask for an IList<T>, they have to dig through documentation, inspect the source code, or (more commonly) guess in order to make the same determination. For example, you’re less likely to mistakenly reverse the arguments to a memcpy-like method that asks for a readonly source because the wrong ordering can fail type checking.

Second, it is better to expose an IReadOnlyList<T>, instead of an IList<T> or an array, when you don’t allow the ability to mutate. This follows the principle of providing what you promise. If you return an IList<T> (that happens to be readonly at runtime) instead of an IReadOnlyList<T>, users will be mislead into trying to modify the result. For example, before following the link to the documentation, tell me whether Dictionary<K, V>.KeyCollection.Remove does the same thing as Dictionary<K, V>.Remove or else fails with a NotSupportedException. The operation makes sense, implying it should do the same thing is Dictionary.Remove, but it’s a bit odd to have a collection you can remove from but not add to, implying it should fail. This question wouldn’t even come up if KeyCollection implemented IReadOnlyCollection<T> instead of ICollection<T>.

Finally, asking for an IReadOnlyList<T>, instead of an IEnumerable<T> that you immediately transform into an IReadOnlyList<T>, is more efficient. You should be asking for what you actually need, so that callers that happen to already have it can avoid unnecessary transformation costs (asking for what you actually need also helps with unit testing). Note that the overload taking IEnumerable<T> can still exist, but it becomes a mere convenience method that delegates to the overload taking an IReadOnlyList<T>. A good example of this optimization is the Enumerable.Reverse method. Consider this slightly-simplified implementation:

public static IEnumerable<T> Reverse<T>(this IEnumerable<T> source) {
    var buffer = source.ToArray();
    for (int i = buffer.Length - 1; i >= 0; --i)
        yield return buffer[i];
}

Enumerable.Reverse has to make a copy of the input sequence, using linear time and consuming linear memory before it can even yield the first item! However, if callers have an IReadOnlyList<T>, the expensive step can be omitted altogether:

public static IEnumerable<T> Reverse<T>(this IReadOnlyList<T> source) {
    for (int i = source.Count - 1; i >= 0; --i)
        yield return source[i];
}

Asking for a list instead of an enumerable reduces both the memory usage and time-to-first-item from linear to constant. Calling this a big improvement is a bit of an understatement. This is not an isolated case either: the cost of lots of other operations drops from linear to constant when working on a list instead of an enumerable. For example: “pick a random item”, “skip the first/last N items”, “take the last N items”, “give me every N’th item”, “partition items into adjacent groups of size N”, not to mention things like binary search and graph traversal (when using an adjacency matrix).

QR: Inline image 1

Posted via email from Jasper-net

Introduction to RPC - Part 1

|
Contents

Introduction

I have worked with client-server applications for a couple of years now, all of these applications use RPC as the layer of communication between the client and the server. I found it strange that no real article existed on this matter here on CodeProject, so I decided to write one of my own to spread my knowledge on this matter.

The matter is, on the other hand, a bit big so I will split it into several articles of different levels of difficulty. This first one is at beginner level.

IDL, RPC and you

In order to use RPC, you need to have some knowledge about IDL, but don't you worry, this article will help you.

Interface Definition Language (IDL)

IDL stands for Interface Definition Language and it's a language for defining interfaces (no kidding). Writing an IDL file is somewhat like writing a C header file with some additional keywords and constructs. IDL is an attributed programming language and thus it can describe parameters, functions and interfaces in more detail than C.

Remote Procedure Call (RPC)

Remote Procedure Call (RPC) defines a powerful technology for creating distributed client/server programs. The RPC runtime libraries manage most of the details relating to network protocols and communication. This enables you to focus on the details of the application rather than the details of the network.

With RPC a client can connect to a server running on another platform. For example: In theory the server could be written for Linux and the client could be written for Win32.  The reality is somewhat more complicated.

Are you scared yet?

If you're not scared, I think it's good time for an example.

The standalone application

This standalone application will not use RPC and it is a simple HelloWorld application that we later will transform into a RPC client/server application.

Read more: Codeproject
QR: Inline image 1

Posted via email from Jasper-net

Task.Wait() vs. await

|
The await keyword is a new keyword in C# 5.0 which, in tandem with async keyword, allows us to easily author methods which execute asynchronously in regards to the calling code. In a previous post I’ve shown a certain issue you should look out for when using the async keyword. In this post we’ll check a similar issue with the await keyword.

The await Trap

Let’s remember our test code from the previous post:

class AsyncClass
{
    public void Process(string s)
    {
        if (s == null) throw new ArgumentNullException("s");

        ProcessCore(s);
    }

    public Task ProcessAsync1(string s)
    {
        if (s == null) throw new ArgumentNullException("s");

        return Task.Run(() => ProcessCore(s));
    }

    public async Task ProcessAsync2(string s)
    {
        if (s == null) throw new ArgumentNullException("s");

        await Task.Run(() => ProcessCore(s));
    }

    private void ProcessCore(string s)
    {
        for (int len = 1; len <= s.Length; len++)
        {
            Thread.Sleep(1000); // This task is very complicated!!
            Console.WriteLine(s.Substring(0, len));
        }
    }
}

What do you think the following code does?

var asyncTest = new AsyncClass();
await asyncTest.ProcessAsync2(null);

Well, you’re probably saying that this time we are actually awaiting the method to complete so it must throw an ArgumentNullException! And, you’re correct – this is indeed the result of the above code. But how about the following code?

var asyncTest = new AsyncClass();
asyncTest.ProcessAsync2(null).Wait();

Hmmmmm… Isn’t this exactly the same as before? Won’t this throw an ArgumentNullException as well? No! It won’t.

QR: Inline image 1

Posted via email from Jasper-net

A Pattern to Dispose WCF Service References

|
Let's say you have a WCF service that implements IMyService. On the client side, you'll have a service reference that derives from ClientBase<IMyService>, which is, in turn, an IDisposable, As I mentioned in the last post, you have two choices:

  • You could follow best practices and "program to an interface," namely IMyService. This is not an IDisposable, so you won't be able to properly Dispose() the reference. 
  • You could abandon your ambition of programming to an interface and use the Client-Base<T>-derived class directly, perhaps with a C# using keyword. This will properly Dispose() the reference.
(We won't mention the worst-of-both-worlds approach in Microsoft's tutorial.)

The first way is bad because it leaves orphaned resources on both the client and the server.

If you use the second method, then you will not be able to use dependency injection. That means your unit tests will depend on a real WCF service. Not only does that mean more setup for your tests, but it means your tests will depend on external software that may or may not be correct. WCF and service-oriented architecture was supposed to avoid exactly this sort of problem.

I'd like to share a solution that has been working quite well for me.

  • Create a class, intended for use on the client side, that derives from IMyService. Let's say this class is called MyServiceProxy.
  • MyServiceProxy implements each method in IMyService by opening the WCF service at the top of a using block, calling the method, and then let the using block Dispose() the service reference.
  • I use dependency injection to inject an instance of IMyService into whatever code needs it. Let's say the consuming class stores the injected instance in a member variable, _myService.
  • The consuming code can then just call _myService.MyMethod().
If the injected instance is the "real" MyServiceProxy class, then MyMethod will open the WCF connection, call MyMethod on the WCF client object, and close the connection.

For unit testing, I can inject a mock of the service. I use the Moq mocking framework, so this is a Mock<IMyService>. The consuming class truly does not care that the mock instance is not an IDisposable. Everything just works.

QR: Inline image 1

Posted via email from Jasper-net

"Understanding OData v3 and WCF Data Services 5.x"

|
Table of Contents

  • Resources

  • What is this Article About?

    This is not your typical “expose an entity framework model as a WCF Data Service” kind of article; in fact I deliberately omitted Entity Framework from this discussion. Now don’t get me wrong, I have nothing against EF, but you will find a lot of great articles on how to set up a WCF Data Service using EF as data source.

    The discussion is around OData v3 and WCF Data Services 5.0 and 5.2. Of course there is no way I cover all new features or every API available, nor do I need so; I will point you to the resources where you can get all information you need. Instead my aim in this article is to discuss some of the topics that usually remain oblivious to the typical WCF Data Services developer.

    Read more: Codeproject
    QR: Inline image 1

    Posted via email from Jasper-net

    Microsoft LNK Vulnerability Brief Technical Analysis(CVE-2010-2568)

    |
    Inline image 2

    A few days ago, an exploit used for highly targeted attacks was published here: CVE-2010-2568 Lnk shortcut. As the blog post, and other posts, state, this is caused by Windows Control Panel's shortcut image display routine. The original blog post shows a stack trace of the exploit results, which also serves to explain the vulnerability.
     
    The nature of the vulnerability is pretty clear. But out of curiosity we did some reverse engineering and here is what we have found. The bug itself is a design flaw as stated by many people and it's very straightforward to locate the point where it happens. The vulnerable file is shell32.dll and the vulnerable routines are Control Panel-related. We loaded the binary on a disassembler and found that the Control Panel file-related routines start with a “CPL_” prefix.
     
    Drawing 1 shows the relations between CPL initialization routines and data flow. The red “LoadLibraryW” API is the vulnerable one.

    Read more: WebSense
    QR: Inline image 1

    Posted via email from Jasper-net

    Creating the Windows 8 user experience

    | Sunday, December 23, 2012
    Inline image 2

        This blog often focuses on the bits and features and less on the “philosophy” or “context” of the product. Given the level of brand new innovations in Windows 8, however, we think it is worth putting Windows 8 in the context in which we approached the design. As with any significant change to a broadly used product, Windows 8 has generated quite a bit of discussion. With millions of people using the Consumer Preview for their daily work, we’ve seen just as many points of view expressed. Many people—from David Pogue of the New York Times to Mat Honan from Gizmodo and many more—have been quite positive, and others less so, most notably in the comments on this blog, where we’ve seen the rich dialog we’d hoped for. Some have asked about design choices we’ve made in the product and the evolution of Windows or suitability of the design to different people. Some bloggers believe it is critical to further separate the traditional desktop from Metro style elements. Other people believe passionately that it is important to make the desktop more like the Metro style interface. There are as many opinions as there are folks who have tried out the Consumer Preview. Designing a new release of a product already used by a billion people in a billion different ways is, as we say, like ordering pizza for a billion people. Doing so out in the open encourages this dialog, and we embrace and value it. Jensen Harris, Director of Program Management for our User Experience team, authored this post. 
    --Steven

    At the D: All Things Digital conference in June 2011, we demonstrated for the first time the new user interface that we developed for Windows 8. This new UI is fast and fluid to use, and optimized for mobile form factors such as laptops, tablets, and convertibles, where people spend the vast majority of their time today. Windows 8 works equally well with mouse, keyboard, or your fingers, and has the best pen support of any OS. It supports multiple displays and the widest array of configurations and form factors of any OS. On top of all that, Windows 8 introduces a new kind of app, which we codenamed “Metro style” following the design language that has evolved going back to Windows Media Center and the new Windows Phone. These apps are immersive, full-screen, beautiful, and optimized for the ways that people commonly use devices today.

    I thought it would be useful to take a step back and describe a little bit of the background of how the Windows 8 user interface was designed, and discuss some of the decisions we’ve made and the goals of this new experience in more detail.

    A brief history of the Windows user interface

    The user interface of Windows has evolved and been transformed over the course of its entire 27-year history. Although we think about certain aspects of the Windows UI as being static or constant, the reality is that the interface is always changing to keep up with the way people use PCs. It is amazing to reflect back on the history of the Windows UI, and to see the level of dramatic change that has transpired over time.

    Read more: Building Windows 8
    QR: Inline image 1

    Posted via email from Jasper-net

    C#/.NET Little Wonders: The Parallel.Invoke() Method

    |
    Once again, in this series of posts I look at the parts of the .NET Framework that may seem trivial, but can help improve your code by making it easier to write and maintain. The index of all my past little wonders posts can be found here.

    Many times in software development, we want to invoke several processes at one time and continue when we get all the results back.  Obviously, if we were needing to process a sequence of items in a similar matter, we could use PLINQ.  Unfortunately, when the things we want to invoke asynchronously are heterogeneous tasks, PLINQ doesn’t really fit the bill.  Today we will look at a handy method in the Parallel class that can help us accomplish this.

    Invoking processes asynchronously

    Let’s say we have three completely separate methods and we want to invoke all three of them and the continue when they have returned.  These methods may be from separate classes and have completely different parameters and/or return types.  Thus, it may not be possible to use facilities like Parallel.ForEach() or PLINQ.

    So how would we do this?  Well, we could obviously create three threads, start them, and join on them to come back:

       1: var threads = new List<Thread>
       2:                   {
       3:                       new Thread(SomeMethod),
       4:                       new Thread(() => SomeOtherMethod(x, y)),
       5:                       new Thread(() => { result = YetAnotherMethod(x, y, z); })
       6:                   };
       7: threads.ForEach(t => t.Start());
       8: threads.ForEach(t => t.Join());

    Which, as you can see, can be used to call any method that fits Thread’s constructor (or can be adapted to it using a lambda, etc.). 

    But that’s a bit heavy.  In addition, if an unhandled exception is thrown in one of those methods it will kill the thread, but we don’t have a very clean way of catching it here at the point of invocation.

    Of course, we also have the Task class from the TPL which can help simplify threads:

       1: var tasks = new []
       2:                 {
       3:                     Task.Factory.StartNew(SomeMethod),
       4:                     Task.Factory.StartNew(() => SomeOtherMethod(x, y)),
       5:                     Task.Factory.StartNew(() => { result = YetAnotherMethod(x, y, z); })
       6:                 };
       7: Task.WaitAll(tasks);

    This simplifies things on the surface, and better yet simplifies things a lot more with exception handling as well (TPL task exceptions get wrapped into a AggregateException and can be caught at the WaitAll() – and other possible places).

    But there’s an even easier way…

    Parallel.Invoke() – Easily invoke asynchronously

    Read more: James Michael Hare
    QR: Inline image 1

    Posted via email from Jasper-net

    Google Play не взломан, однако бесплатно совершать покупки в приложениях можно

    |
         Уважаемые хабровчане, как и обещали, мы с madkite выкладываем в общий доступ хак in-app покупок и проверок лицензий для Google Play. Все, что от вас нужно — рутованное устройство на Android. Работает на телефонах, планшетах, плеерах и даже телевизорах! 

    Сейчас я расскажу, как сие чудо использовать. Для начала, проверяем, что разрешены внешние источники:

    Inline image 1

    Качаем APK файл по следующей ссылке: system.in-appstore.com/freedom/download.php
    Устанавливаеваем его и запускаем (первый запуск может потребовать много времени). Разрешаем root

    Read more: Habrahabr.ru
    QR: Inline image 2

    Posted via email from Jasper-net

    Cast an IEnumerable to an IEnumerable(T)

    |
    It's possible to use LINQ queries to get data from an IEnumerable<T>. But for an IEnumerable, you can't use LINQ. If you write this LINQ query for an IEnumerable:

    IEnumerable ienumerable = new int[] { 1, 5, 6, 7, 8, 11, 10, 134, 90 };
    var integer = from i in ienumerable where i > 10 select i;

    Then, you get this error: Could not find an implementation of the query pattern for source type 'System.Collections.IEnumerable'. 'Where' not found. Consider explicitly specifying the type of the range variable 'i'.  

    In this tip, I tell you how to cast an IEnumerable to an IEnumerable<T>.

    Cast an IEnumerable to an IEnumerable<T>

    To cast an IEnumerable to an IEnumerable<T>, you can use this code:

    IEnumerable ienumerable = new int[] { 1, 5, 6, 7, 8, 11, 10, 134, 90 };
    IEnumerable casted = ienumerable.Cast<int>(); // change 'int' into the type of the elements in your IEnumerable

    ...
    ...

    IEnumerable ienumerable = new object[] { 1, 5, 6, 7, 8, 11, 10, 134, 90, "test" };
    IEnumerable<int> allIntegers = ienumerable.OfType<int>(); // change 'int' in the type of the elements you want to get from the IEnumerable

    Read more: Codeproject
    QR: Inline image 1

    Posted via email from Jasper-net

    Android Tricks: expandable ListView items

    |
    Inline image 2

    The Android notification subsystem was significantly revamped in Jelly Bean. Among the new features, notifications can now be presented in two modes—collapsed and expanded. The user can toggle between the two modes by using a 2-finger swipe gesture, dragging up or down on the item in the notification panel. The GMail notification uses this new feature to present a summary of the new emails received in expanded mode while only giving a count of new mails in collapsed mode:

    I wanted to provide a similar effect in one of my own applications, allowing items in a particular ListView to similarly expand and contract. In my application, there is a list that displays a map image generated with the Google Static Map API in each row. Downloading and instantiating the map image for each row turned out to be very costly and prevented fluid scrolling. That problem led me to the idea of having two modes for the list item—the map image is only instantiated when needed, after the item is expanded.

    The code to support the expanding item is not available as a public API in the framework, so I ported the underlying Java code over to C# and integrated it with ListView to replicate the behavior. I published the three-part code implementation in this Gist on GitHub:
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
    /*
    * Copyright (C) 2010 The Android Open Source Project
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
     
    using System;
     
    using Android.Runtime;
    using Android.Content;
    using Android.Util;
    using Android.Views;
     
    namespace FriendTab
    {
    public class DoubleSwipeDetector
    {
    public interface IOnScaleGestureListener {
     
    bool OnScale(DoubleSwipeDetector detector);
     
    bool OnScaleBegin(DoubleSwipeDetector detector);
     
    void OnScaleEnd(DoubleSwipeDetector detector);
    }
     
    public class SimpleOnScaleGestureListener : IOnScaleGestureListener {
     
    public bool OnScale(DoubleSwipeDetector detector) {
    return false;
    }
     
    public bool OnScaleBegin(DoubleSwipeDetector detector) {
    return true;
    }
     
    public void OnScaleEnd(DoubleSwipeDetector detector) {
    // Intentionally empty
    }
    }
     
    private static float PRESSURE_THRESHOLD = 0.67f;
     
    private Context mContext;
    private IOnScaleGestureListener mListener;
    private bool mGestureInProgress;
     
    private MotionEvent mPrevEvent;
    private MotionEvent mCurrEvent;
     
    private float mFocusX;
    private float mFocusY;
    private float mPrevFingerDiffX;
    private float mPrevFingerDiffY;
    private float mCurrFingerDiffX;
    private float mCurrFingerDiffY;
    private float mCurrLen;
    private float mPrevLen;
    private float mScaleFactor;
    private float mCurrPressure;
    private float mPrevPressure;
    private long mTimeDelta;
     
    private bool mInvalidGesture;
     
    // Pointer IDs currently responsible for the two fingers controlling the gesture
    private int mActiveId0;
    private int mActiveId1;
    private bool mActive0MostRecent;
     
    public DoubleSwipeDetector (Context context, IOnScaleGestureListener listener) {
    mContext = context;
    mListener = listener;
    }
     
    public bool OnTouchEvent (MotionEvent evt) {
    var action = evt.ActionMasked;
     
    if (action == MotionEventActions.Down) {
    reset(); // Start fresh
    }
     
    bool handled = true;
    if (mInvalidGesture) {
    handled = false;
    } else if (!mGestureInProgress) {
    switch (action) {
    case MotionEventActions.Down: {
    mActiveId0 = evt.GetPointerId(0);
    mActive0MostRecent = true;
    }
    break;
     
    case MotionEventActions.Up:
    reset();
    break;
     
    case MotionEventActions.PointerDown: {
    // We have a new multi-finger gesture
    if (mPrevEvent != null) mPrevEvent.Recycle();
    mPrevEvent = MotionEvent.Obtain(evt);
    mTimeDelta = 0;
     
    int index1 = evt.ActionIndex;
    int index0 = evt.FindPointerIndex(mActiveId0);
    mActiveId1 = evt.GetPointerId(index1);
    if (index0 < 0 || index0 == index1) {
    // Probably someone sending us a broken evt stream.
    index0 = findNewActiveIndex(evt, mActiveId1, -1);
    mActiveId0 = evt.GetPointerId(index0);
    }
    mActive0MostRecent = false;
     
    setContext(evt);
     
    mGestureInProgress = mListener.OnScaleBegin(this);
    break;
    }
    }
    } else {
    // Transform gesture in progress - attempt to handle it
    switch (action) {
    case MotionEventActions.Down: {
    // End the old gesture and begin a new one with the most recent two fingers.
    mListener.OnScaleEnd(this);
    int oldActive0 = mActiveId0;
    int oldActive1 = mActiveId1;
    reset();
     
    mPrevEvent = MotionEvent.Obtain(evt);
    mActiveId0 = mActive0MostRecent ? oldActive0 : oldActive1;
    mActiveId1 = evt.GetPointerId(evt.ActionIndex);
    mActive0MostRecent = false;
     
    int index0 = evt.FindPointerIndex (mActiveId0);
    if (index0 < 0 || mActiveId0 == mActiveId1) {
    index0 = findNewActiveIndex(evt, mActiveId1, -1);
    mActiveId0 = evt.GetPointerId(index0);
    }
     
    setContext(evt);
     
    mGestureInProgress = mListener.OnScaleBegin(this);
    }
    break;
     
    case MotionEventActions.PointerUp: {
    int pointerCount = evt.PointerCount;
    int actionIndex = evt.ActionIndex;
    int actionId = evt.GetPointerId(actionIndex);
     
    bool gestureEnded = false;
    if (pointerCount > 2) {
    if (actionId == mActiveId0) {
    int newIndex = findNewActiveIndex(evt, mActiveId1, actionIndex);
    if (newIndex >= 0) {
    mListener.OnScaleEnd(this);
    mActiveId0 = evt.GetPointerId(newIndex);
    mActive0MostRecent = true;
    mPrevEvent = MotionEvent.Obtain(evt);
    setContext(evt);
    mGestureInProgress = mListener.OnScaleBegin(this);
    } else {
    gestureEnded = true;
    }
    } else if (actionId == mActiveId1) {
    int newIndex = findNewActiveIndex(evt, mActiveId0, actionIndex);
    if (newIndex >= 0) {
    mListener.OnScaleEnd(this);
    mActiveId1 = evt.GetPointerId(newIndex);
    mActive0MostRecent = false;
    mPrevEvent = MotionEvent.Obtain(evt);
    setContext(evt);
    mGestureInProgress = mListener.OnScaleBegin(this);
    } else {
    gestureEnded = true;
    }
    }
    mPrevEvent.Recycle();
    mPrevEvent = MotionEvent.Obtain(evt);
    setContext(evt);
    } else {
    gestureEnded = true;
    }
     
    if (gestureEnded) {
    // Gesture ended
    setContext(evt);
     
    // Set focus point to the remaining finger
    int activeId = actionId == mActiveId0 ? mActiveId1 : mActiveId0;
    int index = evt.FindPointerIndex(activeId);
    mFocusX = evt.GetX(index);
    mFocusY = evt.GetY(index);
     
    mListener.OnScaleEnd(this);
    reset();
    mActiveId0 = activeId;
    mActive0MostRecent = true;
    }
    }
    break;
     
    case MotionEventActions.Cancel:
    mListener.OnScaleEnd(this);
    reset();
    break;
     
    case MotionEventActions.Up:
    reset();
    break;
     
    case MotionEventActions.Move: {
    setContext(evt);
     
    // Only accept the evt if our relative pressure is within
    // a certain limit - this can help filter shaky data as a
    // finger is lifted.
    if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
    bool updatePrevious = mListener.OnScale(this);
     
    if (updatePrevious) {
    mPrevEvent.Recycle();
    mPrevEvent = MotionEvent.Obtain(evt);
    }
    }
    }
    break;
    }
    }
     
    return handled;
    }
     
    private int findNewActiveIndex(MotionEvent ev, int otherActiveId, int removedPointerIndex) {
    int pointerCount = ev.PointerCount;
     
    // It's ok if this isn't found and returns -1, it simply won't match.
    int otherActiveIndex = ev.FindPointerIndex(otherActiveId);
     
    // Pick a new id and update tracking state.
    for (int i = 0; i < pointerCount; i++) {
    if (i != removedPointerIndex && i != otherActiveIndex) {
    return i;
    }
    }
    return -1;
    }
     
    private void setContext(MotionEvent curr) {
    if (mCurrEvent != null) {
    mCurrEvent.Recycle();
    }
    mCurrEvent = MotionEvent.Obtain(curr);
     
    mCurrLen = -1;
    mPrevLen = -1;
    mScaleFactor = -1;
     
    MotionEvent prev = mPrevEvent;
     
    int prevIndex0 = prev.FindPointerIndex(mActiveId0);
    int prevIndex1 = prev.FindPointerIndex(mActiveId1);
    int currIndex0 = curr.FindPointerIndex(mActiveId0);
    int currIndex1 = curr.FindPointerIndex(mActiveId1);
     
    if (prevIndex0 < 0 || prevIndex1 < 0 || currIndex0 < 0 || currIndex1 < 0) {
    mInvalidGesture = true;
    if (mGestureInProgress) {
    mListener.OnScaleEnd(this);
    }
    return;
    }
     
    float px0 = prev.GetX(prevIndex0);
    float py0 = prev.GetY(prevIndex0);
    float px1 = prev.GetX(prevIndex1);
    float py1 = prev.GetY(prevIndex1);
    float cx0 = curr.GetX(currIndex0);
    float cy0 = curr.GetY(currIndex0);
    float cx1 = curr.GetX(currIndex1);
    float cy1 = curr.GetY(currIndex1);
     
    float pvx = px1 - px0;
    float pvy = py1 - py0;
    float cvx = cx1 - cx0;
    float cvy = cy1 - cy0;
    mPrevFingerDiffX = pvx;
    mPrevFingerDiffY = pvy;
    mCurrFingerDiffX = cvx;
    mCurrFingerDiffY = cvy;
     
    mFocusX = cx0 + cvx * 0.5f;
    mFocusY = cy0 + cvy * 0.5f;
    mTimeDelta = curr.EventTime - prev.EventTime;
    mCurrPressure = curr.GetPressure(currIndex0) + curr.GetPressure(currIndex1);
    mPrevPressure = prev.GetPressure(prevIndex0) + prev.GetPressure(prevIndex1);
    }
     
    private void reset() {
    if (mPrevEvent != null) {
    mPrevEvent.Recycle();
    mPrevEvent = null;
    }
    if (mCurrEvent != null) {
    mCurrEvent.Recycle();
    mCurrEvent = null;
    }
    mGestureInProgress = false;
    mActiveId0 = -1;
    mActiveId1 = -1;
    mInvalidGesture = false;
    }
     
    public bool IsInProgress {
    get {
    return mGestureInProgress;
    }
    }
     
    public float FocusX {
    get {
    return mFocusX;
    }
    }
     
    public float FocusY {
    get {
    return mFocusY;
    }
    }
     
    public float CurrentSpan {
    get {
    if (mCurrLen == -1) {
    float cvx = mCurrFingerDiffX;
    float cvy = mCurrFingerDiffY;
    mCurrLen = (float)Math.Sqrt (cvx * cvx + cvy * cvy);
    }
    return mCurrLen;
    }
    }
     
    public float CurrentSpanX {
    get {
    return mCurrFingerDiffX;
    }
    }
     
    public float CurrentSpanY {
    get {
    return mCurrFingerDiffY;
    }
    }
     
    public float PreviousSpan {
    get {
    if (mPrevLen == -1) {
    float pvx = mPrevFingerDiffX;
    float pvy = mPrevFingerDiffY;
    mPrevLen = (float)Math.Sqrt (pvx * pvx + pvy * pvy);
    }
    return mPrevLen;
    }
    }
     
    public float PreviousSpanX {
    get {
    return mPrevFingerDiffX;
    }
    }
     
    public float PreviousSpanY {
    get {
    return mPrevFingerDiffY;
    }
    }
     
    public float ScaleFactor {
    get {
    if (mScaleFactor == -1) {
    mScaleFactor = CurrentSpan / PreviousSpan;
    }
    return mScaleFactor;
    }
    }
     
    public long TimeDelta {
    get {
    return mTimeDelta;
    }
    }
     
    public long EventTime {
    get {
    return mCurrEvent.EventTime;
    }
    }
    }
    }

    ExpandableListView is the type that you use to incorporate the control into your own application. You also need to download and put in your resource directory the following two images from the Android framework to provide the glow.

    I use a custom ActivityItem view as my ListView row, which is instantiated from an XML layout containing the following item. When used, the item can be collapsed and expanded. It will start in the collapsed state, as the layout_height property indicates.

    Read more: Xamarin blog
    QR: Inline image 1

    Posted via email from Jasper-net