Hoje a ler a revista MSDN online reparei num artigo que fala sobre implementar I/O assíncrono usando delegados para os callbacks. Imediatamente lembrei-me do projecto que fiz na Inosat, em que para conseguir rede, GPS ou GRPS no dispositivo móvel, usei um sistema parecido com este.
A maior diferença é que, em vez de declarar dois métodos para callback – um em caso de sucesso e outro em caso de falha – usei apenas um, retornando sempre um valor do tipo Result<T>. Por exemplo, se virem no artigo, o autor para o método:
1: public static string ReadAllText(string path);
define a seguinte assinatura:
1: public static void ReadAllTextAsync(string path, Action<string> success, Action<Exception> failure);
em que o primeiro método é chamado se o método correr como esperado, o segundo é invocado se houver algum problema pelo caminho. No meu caso, a definição seria algo como:
1: public static void ReadAllTextAsync(string path, Result<string> success);
em que a classe Result é:
1: public class Result<T>
2: {
3: private readonly T _value;
4: private readonly bool _valid;
5: private readonly string _error;
6:
7: private Result(T value)
8: {
9: _value = value;
10: _valid = true;
11: }
12:
13: private Result(string error) : this()
14: {
15: _error = error;
16: }
17:
18: private Result()
19: {
20: _valid = false;
21: }
22:
23: public static Result<T> Failed()
24: {
25: return new Result<T>();
26: }
27:
28: public static Result<T> Failed(string error)
29: {
30: return new Result<T>(error);
31: }
32:
33: public static Result<T> Success(T value)
34: {
35: return new Result<T>(value);
36: }
37:
38: public T Value
39: {
40: get { return _value; }
41: }
42:
43: public bool Valid
44: {
45: get { return _valid; }
46: }
47:
48: public string Error
49: {
50: get { return _error; }
51: }
52: }
Isto permite que o Result seja usado para notificar se o método teve sucesso ou não e, caso não tenha, que se possa passar o erro que se encontrou.
A diferença que encontro nas duas abordagens é que, no meu caso, quem trata do resultado tem de verificar se a operação teve sucesso chamando o result.Valid. No caso da implementação que está na revista, cada método sabe se o resultado teve sucesso ou não. Para os puristas que defendem a abolição do uso de If’s (já trabalhei com alguns
), isto é puro ouro!

No comments yet
Comentários feed para este artigo