这是我的第一个问题。如果我在询问或格式化方面做错了什么,请告诉我!
我的程序必须在控件中播放某些内容,直到播放完毕,然后继续处理另一项。
以下是整个功能:
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抱怨我可能不会在lambda表达式中使用引用变量。这是合乎逻辑的,因为修改异步任务中的引用变量可能会很糟糕,让我们保持这种状态。
但是,我没有必要修改它,因为它是在程序的其他地方修改的。这就是为什么它是一个引用变量。
是否有一种方法可以以Visual接受的方式读取此变量?也许让它成为只读变量?如果是这样的话,是怎么做的?
谢谢你,利亚姆
发布于 2021-12-13 19:51:17
我找到了我的具体案子的答案。我使变量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甚至可以是包含该字段的类的一种方法。
发布于 2021-12-13 19:50:24
这里有一种方法,您可能想要更改的名称确实很糟糕:
public class Completion : ICompletionNotification
{
public bool IsCompleted { get; private set; }
public void Complete() => IsCompleted = true;
}
public interface ICompletionNotification
{
bool IsCompleted { get; }
}调用代码会创建一个新的Completion,但是您的Play方法使用ICompletionNotification类型的参数。
public void Play(AxWindowsMediaPlayer player, ICompletionNotification completion)...and检查它的IsCompleted属性。
这样,调用方就可以创建一个Completion,并将其传递给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://stackoverflow.com/questions/70339498
复制相似问题