2016-08-05 31 views
0

我想要做的事:.NET網絡API訪問出現InvalidOperationException全局對象

我用WebApiApplication來控制服務器(把它想象成一種民主的音樂播放器的音樂播放器上:我的室友和我所有人都可以通過智能手機訪問它,並可以用相同的方式進行控制)。

網絡調用了這樣:

http://localhost:64199/api/Music?category=Ambient&action=play

http://localhost:64199/api/Music?category=Ambient&action=next

我的控制器看起來是這樣的:

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"); 
    } 

} 

玩家是一個專門的系統。 Windows.Media.MediaP層並實現爲Singleton。它首先在Global.asax中實例化,以隨機歌曲開頭。

每當我嘗試訪問它後(通過網絡調用),應用程序崩潰InvalidOperationException,因爲它無法訪問玩家正在運行的線程。

我想通了與線程會發生什麼:

  1. 線程ID(AppStart的):1 // Global.asax中,螺紋
  2. 線程ID(MediaPlayer的):1
  3. 主題-ID(MusicController):從線程池7 //控制器實例
  4. 線程ID(MediaPlayer的):7個//崩潰,因爲MediaPlayer的實例屬於線程1

正如你所看到的,我對這個問題有了一個概念,但是因爲我對.NET很陌生,所以我只是不知道如何解決它。我需要一個全局唯一的控制器來控制播放器,並由這些ApiControllers調用。

我希望這個問題以前沒有問過,我試圖查看它,但我並不完全知道要搜索什麼。

+0

我不認爲這將永遠不會工作。 WepAPI是一個請求/響應系統。它不會持續打開足夠長的時間來播放歌曲。您將使用WebAPI將歌曲提取到您的應用程序,然後播放它,但您不會從WebAPI播放它。 –

+0

我看到...所以我需要另一個應用程序(例如Windows Media Player或類似的東西),這是告訴 - 沒有要求在網絡通話後播放某首歌曲,以便WebApi可以等待新的電話?謝謝,史蒂芬! – 19CMB94

回答

0

MediaPlayer正在從DispatcherObject繼承,並且聲明:

調度員上創建可以直接訪問DispatcherObject的

只有線程。要從創建DispatcherObject的線程以外的線程訪問DispatcherObject,請在DispatcherObject關聯的Dispatcher上調用Invoke或BeginInvoke。

現在我沒有可用的設置來測試這一點,我不認爲的MediaPlayer類是專爲Web應用程序中使用,但你可以試試這個:

dmp.Dispatcher.Invoke(() => dmp.PlayNext();); 

它將在正確的線程上調用PlayNext方法。如果這不會導致成功,恐怕你必須接受它將無法工作。

+0

謝謝rene,現在發生了一些事情(我不完全知道,但是它不會崩潰)。所以我會仔細看看調度員,也許我可以弄明白 – 19CMB94