Я просто начал возиться с C# /. NET/mono и прочее, и я пытаюсь создать простой плеер песен. Для этого я использую winmm.dll
(не нашел простого кросс-платформенного решения). Проблема заключается в следующем: мне нужно обновить трек-панель вместе с воспроизведением песни. У меня есть две функции: Player.GetLength
и Player.GetCurrentPosition
, которые возвращают время в миллисекундах. Если я назову их «нормально», все будет в порядке. Но мне нужно, чтобы вызвать их в таймере, как это:System.Threading.Timer: Почему он меня ненавидит?
new System.Threading.Timer((state) =>
{
length = Player.GetLength();
pos = Player.GetCurrentPosition();
trackBar1.Value = (pos/length) * 100;
}, null, 0, 100);
Это GetLength
и GetCurrentPosition
похож:
public static int GetLength()
{
StringBuilder s = new StringBuilder(128);
mciSendString("status Song length", s, s.Capacity, IntPtr.Zero);
return int.Parse(s.ToString());
}
Проблема:, когда одна из этих двух функций вызывается, программа просто останавливается, без предупреждения или исключения. Примечание: Я использую .NET
Так мне было интересно, если вы можете объяснить мне, где я получил это неправильно :)
Это работает, но я также хотел бы знать _why_. Не могли бы вы объяснить мне, что происходит? –
В .NET (как и во многих других библиотеках пользовательского интерфейса на многих платформах) элементы управления пользовательского интерфейса не предназначены для доступа из нескольких потоков. Это позволяет им работать быстрее, потому что им не нужно беспокоиться о синхронизации данных. В вашем случае .NET на самом деле бросает исключение, жалуясь на то, что вы пытаетесь получить доступ к пользовательскому интерфейсу из фонового потока, но поскольку он находится в фоновом потоке, вы не видите, что генерируемое исключение. –
Итак, я думаю, что единственный способ взаимодействовать с ними при использовании потоков - это '.Invoke', правильно? –