lambda 表达式中的只读引用变量
Read only reference variable in a lambda expression
这是我的第一个问题。如果我在询问或格式化方面做错了什么,请告诉我!
我的程序必须在 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 接受的方式读取此变量?也许让它成为一个只读变量?如果可以,怎么做?
提前致谢,
利亚姆
这是一种方法,您可能想要更改公认的糟糕名称:
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)
...并检查其 IsCompleted
属性.
这样调用者可以创建一个 Completion
并将其传递给 Play()
方法,该方法将其转换为 ICompletionNotification
.
var completion = new Completion();
Play(player, completion);
调用方可以调用Complete()
表示完成,但接收方不能设置属性。它只能读取它。
CancellationToken
和 CancellationTokenSource
的工作方式几乎相同。正如文档所说,
A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects.
using CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
// pass the token to some method, and then when it's done call
source.Cancel();
同理。创建者可以取消它,但是它传递的令牌只能用于查看操作是否被取消。
我最初并没有推荐它,因为从技术上讲你并没有“取消”任何东西。但它是相同的概念,不需要定义新类型。看到它的人会明白你在做什么,或者可以查阅现有文档。
我找到了我的具体案例的答案。我将变量 audioFileFinished
设为静态变量。在任务中执行的方法现在位于与 audioFileFinished
相同的 class 中。我的函数现在看起来像这样:
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));
}
主要 class 中的方法如下所示:
public static void PlayAfterThis(string path)
{
while (!audioFileFinished)
{
}
localPlayer.URL = path;
}
变量现在被初始化为public static bool audioFileFinished;
感谢@Etienne de Martel 的建议:
Maybe your lambda could even be a method of a class with that field in it.
这是我的第一个问题。如果我在询问或格式化方面做错了什么,请告诉我!
我的程序必须在 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 接受的方式读取此变量?也许让它成为一个只读变量?如果可以,怎么做?
提前致谢, 利亚姆
这是一种方法,您可能想要更改公认的糟糕名称:
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)
...并检查其 IsCompleted
属性.
这样调用者可以创建一个 Completion
并将其传递给 Play()
方法,该方法将其转换为 ICompletionNotification
.
var completion = new Completion();
Play(player, completion);
调用方可以调用Complete()
表示完成,但接收方不能设置属性。它只能读取它。
CancellationToken
和 CancellationTokenSource
的工作方式几乎相同。正如文档所说,
A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects.
using CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
// pass the token to some method, and then when it's done call
source.Cancel();
同理。创建者可以取消它,但是它传递的令牌只能用于查看操作是否被取消。
我最初并没有推荐它,因为从技术上讲你并没有“取消”任何东西。但它是相同的概念,不需要定义新类型。看到它的人会明白你在做什么,或者可以查阅现有文档。
我找到了我的具体案例的答案。我将变量 audioFileFinished
设为静态变量。在任务中执行的方法现在位于与 audioFileFinished
相同的 class 中。我的函数现在看起来像这样:
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));
}
主要 class 中的方法如下所示:
public static void PlayAfterThis(string path)
{
while (!audioFileFinished)
{
}
localPlayer.URL = path;
}
变量现在被初始化为public static bool audioFileFinished;
感谢@Etienne de Martel 的建议:
Maybe your lambda could even be a method of a class with that field in it.