Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Invoke как с ними работать? что это такое вобще? 
:(
    Опции темы
Lеstat
Дата 3.9.2006, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 28.12.2005
Где: Москва

Репутация: нет
Всего: нет



Вобщем пишу программу, которая проигрывает поток Shoutcast'а или Icecast'а
Юзаю библиотеку BASS для .NET
там есть тутор... вобщем посмотрел... там все в одном файле
разобрался немного, написал аналогичную прогу
Потом захотелось вынести все что относится к BASS'у в отдельный класс
переписал, запустил, получил три ошибки в тех местах где были эти Invoke, а именно вот тут
Код

        private void MyDownloadProc(IntPtr buffer, int length, int user)
        {
            if (buffer != IntPtr.Zero && length == 0)
            {
                string txt = Marshal.PtrToStringAnsi(buffer);
                this.Invoke(new UpdateMessageDelegate(UpdateMessageDisplay), new object[] { txt });
            }
        }

        private void MetaSync(int handle, int channel, int data, int user)
        {
            if (data != 0)
            {
                string txt = Marshal.PtrToStringAnsi(new IntPtr(data));
                this.Invoke(new UpdateStatusDelegate(UpdateStatusDisplay), new object[] { txt });
            }
            if (_tagInfo.UpdateFromMETA(data, false))
            { this.Invoke(new UpdateTagDelegate(UpdateTagDisplay)); }
        }


ошибки что-то вроде  "does not contain a definition for 'Invoke'"

помогите разобраться в чем проблема!

PM MAIL ICQ   Вверх
$tatic
Дата 3.9.2006, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 28.1.2005

Репутация: 2
Всего: 22



Мне кажется что этот код принадлежал классу, который наследовался от System.Windows.Forms.Control. Тебе классы надо целиком было переносить ИМХО.
PM MAIL   Вверх
Lеstat
Дата 3.9.2006, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 28.12.2005
Где: Москва

Репутация: нет
Всего: нет



в примере вот так написано  [code=csharp]
public class NetRadio : System.Windows.Forms.Form


Целиком пример воткнуть не могу... даже когда 1/3 вставляю пишет что сообщение слишком большое!



Я хочу сделать по этому примеру класс, создав объект которого можно будет писать что-то вроде 
Код

Radio.Play("url");
Radio.Stop();
Radio.VolumeUp();
Radio.VolumeDown();


накатал пока, а точнее накопировал =)  вот такой класс
тут правда есть еще ошибки, но думаю смогу их решить, а вот про инвоки мало что знаю
Код
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using System.Collections;
using System.Runtime.InteropServices;
using Un4seen.Bass;
using Un4seen.Bass.AddOn.Wma;
using Un4seen.Bass.AddOn.Tags;

namespace SolarNet_Media
{
       class Radio
    {

        private string _url = "http://media.solarnet.ru:8000/live";
        private string _myUserAgent = "Lestat";
        private int _Stream = 0;
        private DOWNLOADPROC myStreamCreateURL;
        private TAG_INFO _tagInfo;
        private SYNCPROC mySync;
        private RECORDPROC myRecProc;
        private int _wmaPlugIn = 0;
        private Boolean isWMA = false;

        public Radio()
        {
            log.Instance.AddLog("Инициализация BASS");
            if (Utils.HighWord(Bass.BASS_GetVersion()) != Bass.BASSVERSION)
            { log.Instance.AddLog("Неверная версия BASS!"); }
            string userAgent = Bass.BASS_GetConfigString((int)BASSConfig.BASS_CONFIG_NET_AGENT);
            Form1.Log(userAgent);
            userAgent = Bass.BASS_SetConfig((int)BASSConfig.BASS_CONFIG_NET_AGENT, _myUserAgent);
            Form1.Log(userAgent);
            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PREBUF, 0); 
            if (Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, 0, null))
            {
                BassWma.LoadMe(); 
                if (Bass.BASS_SetConfig((int)BASSConfig.BASS_CONFIG_MP3_CODEC, true))
                { log.Instance.AddLog("ERROR: " + Enum.GetName(typeof(BASSErrorCode), Bass.BASS_ErrorGetCode())); }
                if (Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_WMA_PREBUF, 0) < 0)
                { log.Instance.AddLog("ERROR: " + Enum.GetName(typeof(BASSErrorCode), Bass.BASS_ErrorGetCode())); }
                myStreamCreateURL = new DOWNLOADPROC(MyDownloadProc);
            }
            else log.Instance.AddLog("Ошибка инициализации BASS!");
        }

        public void Close()
        {
            Bass.BASS_PluginFree(_wmaPlugIn);
            Bass.BASS_Stop();
            Bass.BASS_Free();
            BassWma.FreeMe();
        }

        public void play() {
            _Stream = Bass.BASS_StreamCreateURL(_url, 0, BASSStream.BASS_STREAM_STATUS, myStreamCreateURL, 0);
            if (_Stream == 0){
                _Stream = BassWma.BASS_WMA_StreamCreateFile(_url, 0, 0, BASSStream.BASS_DEFAULT);
                if (_Stream != 0) isWMA = true;  else { log.Instance.AddLog("ERROR..."); return; }}

            _tagInfo = new TAG_INFO(_url);
            Form1.SetStatus("Buffering...");
            if (!isWMA){
                while (true){
                    int len = Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_END);
                    if (len == -1) break;
                    int progress = (
                        Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_DOWNLOAD) -
                        Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_CURRENT)
                        ) * 100 / len;
                    if (progress > 75){break;}
                    Form1.SetStatus(String.Format("Buffering... {0}%", progress));}
            }else{
                while (true){
                    int len = Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_WMA_BUFFER);
                    if (len == -1) break;
                    if (len > 75){break;}
                    Form1.SetStatus(String.Format("Buffering... {0}%", len)); }
            }

            string[] icy = Bass.BASS_ChannelGetTagsICY(_Stream);
            if (icy == null){icy = Bass.BASS_ChannelGetTagsHTTP(_Stream);}
            icy = Bass.BASS_ChannelGetTagsMETA(_Stream);
            if (icy == null){icy = Bass.BASS_ChannelGetTagsOGG(_Stream);}

            if (BassTags.BASS_TAG_GetFromURL(_Stream, _tagInfo)) {
                Form1.SetArtist(_tagInfo.artist);
                Form1.SetTitle(_tagInfo.title);
            }
            mySync = new SYNCPROC(MetaSync);
            Bass.BASS_ChannelSetSync(_Stream, BASSSync.BASS_SYNC_META, 0, mySync, 0);
            Bass.BASS_ChannelSetSync(_Stream, BASSSync.BASS_SYNC_WMA_CHANGE, 0, mySync, 0);

            int rechandle = 0;
            if (Bass.BASS_RecordInit(-1))
            {
                _byteswritten = 0;
                myRecProc = new RECORDPROC(MyRecoring);
                rechandle = Bass.BASS_RecordStart(44100, 2, BASSRecord.BASS_RECORD_PAUSE, myRecProc, 0);
            }
            Form1.SetStatus("Playling...");
            // play the stream
            Bass.BASS_ChannelPlay(_Stream, false);
            // record the stream
            Bass.BASS_ChannelPlay(rechandle, false);        
        }

        private int _byteswritten = 0;
        private byte[] _recbuffer = new byte[1048510]; // 1MB buffer

        private bool MyRecoring(int handle, IntPtr buffer, int length, int user){
            if (length > 0 && buffer != IntPtr.Zero){
                Marshal.Copy(buffer, _recbuffer, 0, length);
                _byteswritten += length;
                Console.WriteLine("Bytes written = {0}", _byteswritten);
                if (_byteswritten < 800000) return true; else return false; } 
            return true;
        }

        private void MyDownloadProc(IntPtr buffer, int length, int user)
        {
            if (buffer != IntPtr.Zero && length == 0)
            {
                string txt = Marshal.PtrToStringAnsi(buffer);
                this.Invoke(new UpdateMessageDelegate(UpdateMessageDisplay), new object[] { txt });
            }
        }

        private void MetaSync(int handle, int channel, int data, int user)
        {
            if (data != 0)
            {
                string txt = Marshal.PtrToStringAnsi(new IntPtr(data));
                this.Invoke(new UpdateStatusDelegate(UpdateStatusDisplay), new object[] { txt });
            }
            if (_tagInfo.UpdateFromMETA(data, false))
            { this.Invoke(new UpdateTagDelegate(UpdateTagDisplay)); }
        }

        public delegate void UpdateTagDelegate();
        private void UpdateTagDisplay()
        {
            Form1.SetArtist(_tagInfo.artist);
            Form1.SetTitle(_tagInfo.title);
        }

        public delegate void UpdateStatusDelegate(string txt);
        private void UpdateStatusDisplay(string txt)
        {
            Form1.SetStatus(txt);
        }

        public delegate void UpdateMessageDelegate(string txt);
        private void UpdateMessageDisplay(string txt)
        {
            Form1.SetArtist("Tags: " + txt + Environment.NewLine);
        }

    }
}



а он с этими инвоками не работает =(

Это сообщение отредактировал(а) Lеstat - 3.9.2006, 15:50
PM MAIL ICQ   Вверх
$tatic
Дата 3.9.2006, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 28.1.2005

Репутация: 2
Всего: 22



Короче, как я понял, в примере на форму выводилась вся инфа о текущей мелодии. По типу плеера. Все раньше было в классе, который являлся формой и это потоковое радио представлял. Когда ты перенес код примера в отдельный класс естественно все перестало работать. Самым простым выходом будет либо при создании класса указывать форму, на которую будет идти инфа (в этом случае this.invoke меняется на form.invoke или что-то аналогичное), либо использовать другой метод получения инфы (например создать класс с полями Title, Artist и т.п.).
А вызовы делегатов (с помощью метода invoke) просто отправляют некоторую инфу на форму.
Тебе надо просто разобраться с кодом примера и сделать именно отдельный класс.
Будут какие вопросы - задавай здесь или в асе.
PM MAIL   Вверх
Lеstat
Дата 3.9.2006, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 28.12.2005
Где: Москва

Репутация: нет
Всего: нет



я так понимаю в этом классе нужно событие делать?
invoke вобще для чего нужно? что оно делает?
его как-нибудь можно заменить в просто классе, не в форме
PM MAIL ICQ   Вверх
$tatic
Дата 3.9.2006, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 28.1.2005

Репутация: 2
Всего: 22



фактически invoke вызывает функцию, передаваемую делегатом, и при желании разработчика передает ей параметры.
В общем читай MSDN.
Например код
Код

this.Invoke(new UpdateMessageDelegate(UpdateMessageDisplay), new object[] { txt });

создает делегат для функции UpdateMessageDisplay и вызывает ее. А поскольку ей требуется параметр, то он (txt) передается в массиве объектов.
В результате получается вызов
Код

UpdateMessageDisplay(txt);

но выполняется он в том потоке, который владеет низкоуровневым хендлом формы.

Это сообщение отредактировал(а) $tatic - 3.9.2006, 19:29
PM MAIL   Вверх
stab
Дата 3.9.2006, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

Репутация: 22
Всего: 48



Form.Invoke вызывает метод, передынный ему в качестве параметра (new UpdateMessageDelegate(UpdateMessageDisplay)), в контексте WinForms потока приложения, с заданными параметрами  (new object[] { txt }).

Код который ты накопировал ориентирован на работу в несколько потоков. На сколько я понял из обрезков, в одном потоке осуществляется скачивание, во втором проигрывание, в третьем, потоке WinForms, управление и индикация.

Пока с потокам не разберёшся работать у тебя ничего не будет. Короче, учите мат. часть. Будут вопросы - всегда рады.


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Lеstat
Дата 3.9.2006, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 28.12.2005
Где: Москва

Репутация: нет
Всего: нет



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

Код

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using System.Collections;
using System.Runtime.InteropServices;
using Un4seen.Bass;
using Un4seen.Bass.AddOn.Wma;
using Un4seen.Bass.AddOn.Tags;

namespace SolarNet_Media
{
       class Radio
    {

        private string _url = "http://media.solarnet.ru:8000/live";
        private string _myUserAgent = "Lestat";
        private int _Stream = 0;
        private DOWNLOADPROC myStreamCreateURL;
        private TAG_INFO _tagInfo;
        private SYNCPROC mySync;
        private RECORDPROC myRecProc;
        private int _wmaPlugIn = 0;
        private Boolean isWMA = false;

        public Radio()
        {
            //log.Instance.AddLog("Инициализация BASS");
            if (Utils.HighWord(Bass.BASS_GetVersion()) != Bass.BASSVERSION)
            { //log.Instance.AddLog("Неверная версия BASS!");
            }
            string userAgent = Bass.BASS_GetConfigString((int)BASSConfig.BASS_CONFIG_NET_AGENT);
           // Form1.Log(userAgent);
            userAgent = Bass.BASS_SetConfig((int)BASSConfig.BASS_CONFIG_NET_AGENT, _myUserAgent);
           // Form1.Log(userAgent);
            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PREBUF, 0); 
            if (Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, 0, null))
            {
                BassWma.LoadMe(); 
                if (Bass.BASS_SetConfig((int)BASSConfig.BASS_CONFIG_MP3_CODEC, true))
                { log.Instance.AddLog("ERROR: " + Enum.GetName(typeof(BASSErrorCode), Bass.BASS_ErrorGetCode()).ToString()); }
                if (Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_WMA_PREBUF, 0) < 0)
                { log.Instance.AddLog("ERROR: " + Enum.GetName(typeof(BASSErrorCode), Bass.BASS_ErrorGetCode()).ToString()); }
               // myStreamCreateURL = new DOWNLOADPROC(MyDownloadProc);
            }
            else log.Instance.AddLog("Ошибка инициализации BASS!");
        }

        public void Close()
        {
            Bass.BASS_PluginFree(_wmaPlugIn);
            Bass.BASS_Stop();
            Bass.BASS_Free();
            BassWma.FreeMe();
        }

        public void play() {
            _Stream = Bass.BASS_StreamCreateURL(_url, 0, BASSStream.BASS_STREAM_STATUS, myStreamCreateURL, 0);
            if (_Stream == 0){
                _Stream = BassWma.BASS_WMA_StreamCreateFile(_url, 0, 0, BASSStream.BASS_DEFAULT);
                if (_Stream != 0) isWMA = true;  else { log.Instance.AddLog("ERROR..."); return; }}

            _tagInfo = new TAG_INFO(_url);
            Form1.SetStatus("Buffering...");
            if (!isWMA){
                while (true){
                    int len = Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_END);
                    if (len == -1) break;
                    int progress = (
                        Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_DOWNLOAD) -
                        Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_CURRENT)
                        ) * 100 / len;
                    if (progress > 75){break;}
                    Form1.SetStatus(String.Format("Buffering... {0}%", progress));}
            }else{
                while (true){
                    int len = Bass.BASS_StreamGetFilePosition(_Stream, BASSStreamFilePosition.BASS_FILEPOS_WMA_BUFFER);
                    if (len == -1) break;
                    if (len > 75){break;}
                    Form1.SetStatus(String.Format("Buffering... {0}%", len)); }
            }

            string[] icy = Bass.BASS_ChannelGetTagsICY(_Stream);
            if (icy == null){icy = Bass.BASS_ChannelGetTagsHTTP(_Stream);}
            icy = Bass.BASS_ChannelGetTagsMETA(_Stream);
            if (icy == null){icy = Bass.BASS_ChannelGetTagsOGG(_Stream);}

            if (BassTags.BASS_TAG_GetFromURL(_Stream, _tagInfo)) {
                Form1.SetArtist(_tagInfo.artist);
                Form1.SetTitle(_tagInfo.title);
            }
            mySync = new SYNCPROC(MetaSync);
            Bass.BASS_ChannelSetSync(_Stream, BASSSync.BASS_SYNC_META, 0, mySync, 0);
            Bass.BASS_ChannelSetSync(_Stream, BASSSync.BASS_SYNC_WMA_CHANGE, 0, mySync, 0);

            int rechandle = 0;
            if (Bass.BASS_RecordInit(-1))
            {
                _byteswritten = 0;
                myRecProc = new RECORDPROC(MyRecoring);
                rechandle = Bass.BASS_RecordStart(44100, 2, BASSRecord.BASS_RECORD_PAUSE, myRecProc, 0);
            }
            Form1.SetStatus("Playling...");
            // play the stream
            Bass.BASS_ChannelPlay(_Stream, false);
            // record the stream
            Bass.BASS_ChannelPlay(rechandle, false);        
        }

        private int _byteswritten = 0;
        private byte[] _recbuffer = new byte[1048510]; // 1MB buffer

        private bool MyRecoring(int handle, IntPtr buffer, int length, int user){
            if (length > 0 && buffer != IntPtr.Zero){
                Marshal.Copy(buffer, _recbuffer, 0, length);
                _byteswritten += length;
                Console.WriteLine("Bytes written = {0}", _byteswritten);
                if (_byteswritten < 800000) return true; else return false; } 
            return true;
        }


        private void MetaSync(int handle, int channel, int data, int user)
        {
            if (data != 0)
            {
                string txt = Marshal.PtrToStringAnsi(new IntPtr(data));
                //this.Invoke(new UpdateStatusDelegate(UpdateStatusDisplay), new object[] { txt });
            }
            if (_tagInfo.UpdateFromMETA(data, false))
            { //form.Invoke(new UpdateTagDelegate(UpdateTagDisplay)); 
            }
        } 

    }
}


PM MAIL ICQ   Вверх
mr.DUDA
Дата 3.9.2006, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Lеstat @  3.9.2006,  19:45 Найти цитируемый пост)
Там все эти умные инвоки, насколько я понял, что-то вроде события чтоли создают...  для того чтобы обновлять теги артист, трек и тд, когда они меняются

Читай, что выше Pegas пишет:


Цитата(cully @  3.9.2006,  19:37 Найти цитируемый пост)
Form.Invoke вызывает метод, передынный ему в качестве параметра , в контексте WinForms потока приложения...




--------------------
user posted image
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0826 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.