這是我在這里的第一個問題。如果我在詢問或格式化方面做錯了什么,請告訴我!
我的程式必須在 Windows Media Player 控制元件中播放某些內容,等待播放完畢,然后繼續播放另一個專案。
下面是整個函式:
public void Play(AxWindowsMediaPlayer player, ref bool audioFileFinished)
{
int numberOfIntro = rnd.Next(songIntros.Count); //Randomly select an intro from the list
string introFilePath = songIntros.ElementAt(numberOfIntro).fullPath;
player.URL = introFilePath;
//This task is necessary because the while (!audioFileFinished) will otherwise run in the UI and hang the app.
Task f = Task.Factory.StartNew(() =>
{
while (!audioFileFinished)
{
}
player.URL = fullPath;
});
}
當然,Visual Studio 抱怨我可能不會在 lambda 運算式中使用參考變數。這是合乎邏輯的,因為在異步任務中修改參考變數會很糟糕,讓我們保持不變。
但是,我不需要修改它,因為它在程式的其他地方被修改了。這就是為什么它是一個參考變數。
有沒有辦法以 Visual Studio 接受的方式讀取這個變數?也許使它成為只讀變數?如果是這樣,如何?
提前致謝,利亞姆
uj5u.com熱心網友回復:
我找到了我的具體案例的答案。我使變數audioFileFinished成為靜態變數。要在任務中執行的方法現在位于與audioFileFinished. 我的函式現在看起來像這樣:
public void Play(AxWindowsMediaPlayer player)
{
int numberOfIntro = rnd.Next(songIntros.Count); //Randomly select an intro from the list
string introFilePath = songIntros.ElementAt(numberOfIntro).fullPath;
player.URL = introFilePath;
//This task is necessary because the while (!audioFileFinished) will otherwise run in the UI and hang the app.
Task f = Task.Factory.StartNew(() => Radio.PlayAfterThis(fullPath));
}
主類中的方法如下所示:
public static void PlayAfterThis(string path)
{
while (!audioFileFinished)
{
}
localPlayer.URL = path;
}
變數現在被初始化為 public static bool audioFileFinished;
感謝@Etienne de Martel 提出以下建議:
也許您的 lambda 甚至可以是包含該欄位的類的方法。
uj5u.com熱心網友回復:
這是一種方法,您可能想更改一些公認的糟糕名稱:
public class Completion : ICompletionNotification
{
public bool IsCompleted { get; private set; }
public void Complete() => IsCompleted = true;
}
public interface ICompletionNotification
{
bool IsCompleted { get; }
}
呼叫代碼創建一個 new Completion,但您的Play方法采用型別引數ICompletionNotification
public void Play(AxWindowsMediaPlayer player, ICompletionNotification completion)
...并檢查其IsCompleted屬性。
這樣呼叫者就可以創建 aCompletion并將其傳遞給將Play()其轉換為ICompletionNotification.
var completion = new Completion();
Play(player, completion);
呼叫者可以呼叫Complete()以表明它已完成,但接收者不能設定該屬性。它只能讀取它。
CancellationToken并以CancellationTokenSource幾乎相同的方式作業。正如檔案所說,
CancellationToken 啟用執行緒、執行緒池作業項或任務物件之間的協作取消。
using CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
// pass the token to some method, and then when it's done call
source.Cancel();
這是同樣的想法。創建者可以取消它,但它傳遞只能用于查看操作是否已取消的令牌。
我最初并沒有推薦它,因為從技術上講,您并沒有“取消”任何東西。但它是相同的概念,不需要定義新型別。看到它的人會明白你在做什么,或者可以查找現有的檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/389789.html
