Есть такая задача:
// Задача: вызывать Fun и получить "n".
//
// После этого последовательны должны быть вызваны:
//
// Action2 (кроме случаев, когда "n" не делится на 2)
// Action3 (кроме случаев, когда "n" не делится на 3)
// Action4 (кроме случаев, когда "n" не делится на 4)
Задача совершенно практическая. Fun может возвращать список необходимых обновлений, а Action2-Action4 производить эти обновления.
В синхронном варианте это решается так:
var service = new Service();
// Синхронный вариант
{
int n = service.Fun();
if (0 == n%2)
service.Action2();
if (0 == n%3)
service.Action3();
if (0 == n%4)
service.Action4();
Console.WriteLine("Complete");
}
Как видим -- ничего сложного. Можно добавлять сколько угодно Action -- сложность системы от этого не будет возрастать.
А теперь попробуем написать асинхронный вариант. Замечу, что потребность взята не с потолка -- при использовании Windows Phone нет возможности вызова веб-методов синхронно -- только асинхронный вариант. У меня получилось вот что:
var service = new Service();
// Асинхронный вариант 1
{
service.FunCompleted += (sender, eventArgs) =>
{
int n = eventArgs.Argument;
if (0 == n % 2)
{
service.Action2Completed +=
(o, myEventArgs) =>
{
if (0 == n % 3)
{
service.Action3Completed
+= (sender1, args1) =>
{
if (0 == n % 4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
};
service.StartAction3();
}
else
{
if (0 == n % 4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
}
};
service.StartAction2();
}
else
{
if (0 == n % 3)
{
service.Action3Completed
+= (o, myEventArgs) =>
{
if (0 == n%4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
};
service.StartAction3();
}
else
{
if (0 == n % 4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
}
}
};
service.StartFun();
}
Обратите внимание: сложность нарастает по геометрической прогрессии! Для 3х Action имеем 7 условий. Для 4х их будет в 2 раза больше и так далее...
И, собственно, вопрос. Что делать, если таких вот Action в проекте действительно много? Как быть, как написать? Это ж идиотизм какой-то.
Для удобства привожу упрощенный код полностью:
| Скрытый текст |
| using System;
using System.Threading;
namespace ConsoleApplication17
{
class Program
{
class MyEventArgs : EventArgs
{
public int Argument { get; set; }
}
private class Service
{
public event EventHandler<MyEventArgs> FunCompleted;
public event EventHandler Action2Completed;
public event EventHandler Action3Completed;
public event EventHandler Action4Completed;
public void StartFun()
{
(new Thread(() =>
{
Thread.Sleep(1000);
FunCompleted(this, new MyEventArgs { Argument = DateTime.Now.Second });
})).Start();
}
public void StartAction2()
{
(new Thread(() =>
{
Thread.Sleep(1000);
Action2Completed(this, null);
})).Start();
}
public void StartAction3()
{
(new Thread(() =>
{
Thread.Sleep(1000);
Action3Completed(this, null);
})).Start();
}
public void StartAction4()
{
(new Thread(() =>
{
Thread.Sleep(1000);
Action4Completed(this, null);
})).Start();
}
// Синхронный вариант
public int Fun()
{
return DateTime.Now.Second;
}
public void Action2()
{
}
public void Action3()
{
}
public void Action4()
{
}
}
static void Main(string[] args)
{
// Задача: вызывать Fun 1 и получить "n".
//
// После этого последовательны должны быть вызваны:
//
// Action2 (кроме случаев, когда "n" не делится на 2)
// Action3 (кроме случаев, когда "n" не делится на 3)
// Action4 (кроме случаев, когда "n" не делится на 4)
var service = new Service();
// Синхронный вариант
{
int n = service.Fun();
if (0 == n%2)
service.Action2();
if (0 == n%3)
service.Action3();
if (0 == n%4)
service.Action4();
Console.WriteLine("Complete");
}
// Асинхронный вариант 1
{
service.FunCompleted += (sender, eventArgs) =>
{
int n = eventArgs.Argument;
if (0 == n % 2)
{
service.Action2Completed +=
(o, myEventArgs) =>
{
if (0 == n % 3)
{
service.Action3Completed
+= (sender1, args1) =>
{
if (0 == n % 4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
};
service.StartAction3();
}
else
{
if (0 == n % 4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
}
};
service.StartAction2();
}
else
{
if (0 == n % 3)
{
service.Action3Completed
+= (o, myEventArgs) =>
{
if (0 == n%4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
};
service.StartAction3();
}
else
{
if (0 == n % 4)
{
service.Action4Completed +=
(o1, eventArgs1) =>
{
Console.WriteLine(
"Complete");
};
service.StartAction4();
}
}
}
};
service.StartFun();
}
Console.ReadLine();
}
}
}
|
| |