AudioPlayerAgent,定时器和web服务 [英] AudioPlayerAgent, timer and webservice

查看:107
本文介绍了AudioPlayerAgent,定时器和web服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序读取Shoutcast一样。

my application read a shoutcast.

播放的音乐的元数据是从我返回一个JSON一个Web服务收集的(所以我没有脱code中的流)。我所说的Web服务每20秒计时器,这部作品在我的应用程序,但确实在AudioPlayer.cs没有作品

The meta data of the music played is collected from a webservice that return me a Json (so i don't have to decode the stream). I call the webservice every 20 seconds with a timer, this works in my application, but doesn't works in the AudioPlayer.cs

    //Timer
    private DispatcherTimer timer;


    /// <remarks>
    /// AudioPlayer instances can share the same process. 
    /// Static fields can be used to share state between AudioPlayer instances
    /// or to communicate with the Audio Streaming agent.
    /// </remarks>
    public AudioPlayer()
    {
        if (!_classInitialized)
        {
            _classInitialized = true;
            // Subscribe to the managed exception handler
            Deployment.Current.Dispatcher.BeginInvoke(delegate
            {
                Application.Current.UnhandledException += AudioPlayer_UnhandledException;

            });
        }

        //I activate the timer
        timer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(20) // <------- Error here UnauthorizedAccessException was unhandled. Invalid cross-thread access.
        };
        timer.Tick += timer_Tick;
        timer.Start();
    }


    private void timer_Tick(object sender, EventArgs e)
    {
        HttpWebRequest request = WebRequest.Create("http://127.0.0.81:8003/getmeta") as HttpWebRequest;
        request.BeginGetResponse(new AsyncCallback(AsyncBack), request);
    }

    private void AsyncBack(IAsyncResult ias)
    {
            HttpWebRequest req = (HttpWebRequest)ias.AsyncState;

            try
            {
                using (HttpWebResponse res = req.EndGetResponse(ias) as HttpWebResponse)
                {
                    StreamReader stream = new StreamReader(res.GetResponseStream());
                    String jsonToParse = stream.ReadToEnd();
                    JObject jObject = JObject.Parse(jsonToParse);

                    AudioTrack track = BackgroundAudioPlayer.Instance.Track;

                    track.BeginEdit();
                    track.Title = (string) jObject["title"];
                    track.Artist = (string) jObject["artist"];
                    track.Album = (string) jObject["album"];
                    track.EndEdit();


                    res.Close();
                }
            }
            catch (WebException e)
            {
                timer.Stop();
            }
    }

感谢大家的帮助。

Thanks you for the help

推荐答案

的AudioPlayer类是相当独特的。它仅住的时间小周期。在使用该BackgroundAudioPlayer的应用程序,你要跟实施AudioPlayer类只会活路来完成改变播放状态的任务。所以,当用户开始玩的东西,你的AudioPlayer类的实例将被创建完成开始播放的任务。一旦你的OnUserAction或OnPlayStateChanged中调用NotifyComplete(),您的AudioPlayer的实例消失。

The AudioPlayer class is quite unique. It only lives for a small period of time. In an application that uses the BackgroundAudioPlayer, yous implementation of the AudioPlayer class will only stay alive to accomplish the task of changing play state. So, when a user begins playing something, an instance of your AudioPlayer class will be created to accomplish the task of begin playing. Once you call NotifyComplete() within the OnUserAction or OnPlayStateChanged, the instance of your AudioPlayer goes away.

后台线程的AudioPlayer与关联仍将活跃,你可以有一个线程中活着的其他对象,但AudioPlayer将被终止。就是在这个与_classInitialized场创建提示默认AudioPlayer。这是静态的,因为AudioPlayer将创建很多次,但我们只希望subscrrbe该事件一次。

The background thread that the AudioPlayer is associated with will still be active and you can have other objects alive within that thread, but the AudioPlayer will be terminated. The default AudioPlayer that is created hints at this with the _classInitialized field. This is static because the AudioPlayer will be created many times, but we only want to subscrrbe to that event once.

我建议两件事情之一。首先是当你需要前进到下一首歌曲只得到JSON响应。你不会叫NotifyComplete(),直到响应返回之后。
下面是一些伪code:

I would suggest one of two things. The first is to only get the json response when you need to advance to the next song. You would not call NotifyComplete() until after the response has returned. Here is some pseudo code:

override OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param)
{
    GetJsonResponse();
}
private void GetJsonResponce()
{
    // async call to your service
    // When async completes:
    track.BeginEdit();
    track.Title = (string) jObject["title"];
    track.Artist = (string) jObject["artist"];
    track.Album = (string) jObject["album"];
    track.EndEdit();
    NotifyComplete();
}

二是将有一类,这是否在后台运行。那类将有一个静态属性来获取这是在线程活着的实例。那么你的AudioPlayer会得到它从该对象需要的信息

The second would be to have a class that does this in the background. That class would have a static property to get the instance that is alive in the thread. Then your AudioPlayer would get the info it needs from that object

public class Songs
{
    static Songs _instance;
    public static Songs Instance
    { 
        get { return _instance ?? new Songs(); }
    }
    // Do you timer stuff here

    // Allow the ability to access the timer stuff also.
}
// in AudioPlayer
override OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param)
{
    Songs.Instance.GetStuff
    NotifyComplete();
}

这篇关于AudioPlayerAgent,定时器和web服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆