访问全局对象时出现.NET Web Api InvalidOperationException
本文关键字:NET Web Api InvalidOperationException 全局 对象 访问 | 更新日期: 2023-09-27 18:01:02
我要做的事情:
我使用WebApiApplication来控制服务器上的音乐播放器(把它想象成一种民主的音乐播放器:我和我的室友都可以通过智能手机访问它,并且可以用同样的方式控制它(。
网络呼叫是这样进行的:
http://localhost:64199/api/Music?category=Ambient&action=播放
或
http://localhost:64199/api/Music?category=Ambient&动作=下一个
我的控制器看起来像这样:
public class MusicController : ApiController
{
const string MUSICPATH = @"...'Songs";
public HttpResponseMessage Get(string category, string action, string song = "", bool shuffle = false)
{
// DirMusicPlayer.Category = category;
DirMediaPlayer dmp = DirMediaPlayer.getInstance(category);
System.Diagnostics.Debug.WriteLine("Thread-ID (Ctrl): " + Thread.CurrentThread.ManagedThreadId);
switch (action)
{
case "play":
if (song.Equals(""))
{
dmp.PlayAll();
}
else
{
dmp.PlaySong(song);
}
break;
case "stop":
dmp.Stop();
break;
case "next":
dmp.PlayNext();
break;
case "prev":
dmp.PlayPrevious();
break;
case "shuffle":
dmp.Shuffle = shuffle;
break;
default:
break;
}
return Request.CreateResponse(HttpStatusCode.OK, "Playing");
}
}
播放器是一个专门的System.Windows.Media.MediaPlayer,并作为一个Singleton实现。它首先在Global.asax中实例化,从一首随机歌曲开始。
每当我稍后尝试访问它(通过web调用(时,应用程序都会崩溃,并出现InvalidOperationException,因为它无法访问播放器运行的线程。
我已经弄清楚线程会发生什么:
- 线程ID(AppStart(:1//Global.asax-Thread
- 线程ID(MediaPlayer(:1
- 线程ID(MusicController(:7//线程池中的控制器实例
- 线程ID(MediaPlayer(:7//崩溃,因为Media Player实例属于线程1
正如你所看到的,我知道问题是什么,但由于我对.NET还很陌生,我不知道如何解决它。我需要一个全局唯一控制器来控制播放器,并由那些ApiControllers调用。
我希望这个问题以前没有人问过,我试着查了一下,但我不知道该找什么。
MediaPlayer是从DispatcherObject继承的,它声明:
只有在其上创建Dispatcher的线程才能直接访问DispatcherObject。要从创建DispatcherObject的线程以外的线程访问Dispatcher对象,请在与DispatcherObject关联的Dispatcher上调用Invoke或BeginInvoke。
现在我没有可用的设置来测试这一点,我不认为MediaPlayer类是为在Web应用程序中使用而设计的,但你可以尝试一下:
dmp.Dispatcher.Invoke(() => dmp.PlayNext(); );
它将在正确的线程上调用PlayNext
方法。如果这不能带来成功,恐怕你必须接受这是行不通的。