Отправляет email-рассылки с помощью сервиса Sendsay

[prg] События в C#

Привет уважаемому собранию.

Никак не разберусь с событиями. Покажите, плз, конкретный пример кода (с
краткими комментариями) для C#. Есть переменная int i. Нужно, чтобы
когда в переменной появлялось определённое значение, скажем, 5,
срабатывало событие, скажем, проигрывался звук Console.Beep(3000,250).
Как отслеживать изменения этой переменной? Через таймер что ли?
Запускать таймер и каждые 1 мс следить, что появилось в int i? Или есть
более гуманный способ?

Ответить   Mon, 17 Dec 2018 05:40:19 +0300 (#3597075)

 

Ответы:

Здравствуйте.

17.12.2018 5:40, Кирилл пишет:

Вообще суть в том, что событие вызывается методом, который изменяет само
значение переменной.

Далее пример от сюда:
https://docs.microsoft.com/ru-ru/dotnet/api/system.eventhandler?view=netframework-4.7.2

public class ThresholdReachedEventArgs : EventArgs // класс
унаследованный от EventArgs , в котором передаются параметры события, в
данном случае пороговое значение и время, в вашем случае это могло быть
значение переменной i
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}

class Counter //класс в котором происходит какое-то событие
{

public event EventHandler<ThresholdReachedEventArgs>
ThresholdReached; // событие на которое будут подписываться получатели и
которое будет вызываться при добавлении значения

private int threshold;
private int total;

public Counter(int passedThreshold)
{
threshold = passedThreshold;
}

public void Add(int x) // метод, где добавляется значение и
вызывается событие
{
total += x;
if (total >= threshold) // если total превышает какой-то
порог вызвать событие
{
ThresholdReachedEventArgs args = new
ThresholdReachedEventArgs(); // создаем объект класса
ThresholdReachedEventArgs , определенного выше, и заполняем его значениями
args.Threshold = threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args); // вызываем метод вызывающий
само событие и передаем ему данные
}
}

protected virtual void
OnThresholdReached(ThresholdReachedEventArgs e) // метод вызывающий событие
{
EventHandler<ThresholdReachedEventArgs> handler =
ThresholdReached;
if (handler != null) // проверяет делегат события на null и
вызывает его
{
handler(this, e);
}
}

Дальше вы можете подписываться на это событие следующим образом:

class Program
{
static void Main(string[] args)
{
Counter c = new Counter(new Random().Next(10)); // Создаем
экземпляр класса Counter

c.ThresholdReached += c_ThresholdReached; // подписываемся на событие
ThresholdReached
}

static void c_ThresholdReached(object sender,
ThresholdReachedEventArgs e) // метод, который будет вызываться, когда
срабатывает событие
{
Console.WriteLine("The threshold of {0} was reached at
{1}.", e.Threshold, e.TimeReached);
Environment.Exit(0);
}
}

--

С уважением, Константин.

Ответить   Mon, 17 Dec 2018 13:46:01 +0300 (#3597131)

 

Здравствуйте Константин!
Все вроде по фэншую, но пробовали ли данный трюк на параллельных процессах в
одном приложении?
Сам пробовал в рамках одного класса, но не параллерил.
Кто-то писал, что ошибки лезут.
Может всезанятость переменной добавить?
Удачи!

Ответить   Mon, 17 Dec 2018 23:50:15 +1000 (#3597233)

 

здравствуйте.

помогите пожалуйста в следующем вопросе.
может это относится не только к bass.net но и вчастности к самому bass.

есть класс, из которого создаются \кземляры в foreach цыкле и инициализирует
bass с нужным звуковым устройством из конфига.

проблема в том, что bass запоминает устройство последнего созданного
инстанса и далее все инстансы выводят звук именно на этот девайс.

что я делаю не так?

фрагмент кода инициализации bass

public class Player
{

public Player(string dev)
{
for (int deviceId = 1; deviceId < Bass.BASS_GetDeviceCount();
deviceId++)
{
BASS_DEVICEINFO device = Bass.BASS_GetDeviceInfo(deviceId);
if (device.name == dev)
{
Bass.BASS_Init(deviceId, 44100,
BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
}
}
}

public void showdev()
{

MessageBox.Show(Bass.BASS_GetDeviceInfo(Bass.BASS_GetDevice()).name);
}
}

фрагмент, где создаются инстансы

List<Player> players = new List<Player>();
foreach (Section sec in config) {
var playInstance = new Player(sec["device"].StringValue);
players.Add(playInstance);
}

и цикл, где явно отображаются одинаковые устройства
foreach (Player p in players)
{
p.showdev();
}

как сделать так, что бы для каждого инстанса устанавливалось свое отдельное
устройство?

спасибо

Ответить   Thu, 20 Dec 2018 08:46:51 +0400 (#3597574)

 

Здравствуйте.

Я не работал с bass.net, но насколько могу судить, тут проблема в том,
что вы во всех своих классах используете один и тот же статический класс
библиотеки, то есть все классы используют один экземпляр bass,
соответственно, если один что-то в нем меняет, он изменяется для всех.

Решением может быть, либо найти возможность создавать отдельный
экземпляр класса bass для каждого вашего класса, либо просто сделать так
чтобы каждый экземпляр вашего класса хранил свое собственное устройство
и когда ему нужно использовать библиотеку переключал её на использование
соответствующего, либо в библиотеки есть возможность указывать
устройство просто как дополнительный параметр, к примеру, во время
воспроизведения файла.

Ответить   Thu, 20 Dec 2018 11:46:21 +0300 (#3597593)

 

здравствуйте.

к сожалению при чтении инструкции bass.net большенство классов и методов
статические.
но я нашел метод Bass_SetDevice который может направить звук до
проигрывания.

простой метод GetDeviceIDByName(string dev) который я написал для возврата
индекса нужного устройства и передачи этого индекса выше приведенному методу
решил задачу.

спасибо.

Ответить   Thu, 20 Dec 2018 16:40:30 +0400 (#3597639)