首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >只读取lambda表达式中的引用变量

只读取lambda表达式中的引用变量
EN

Stack Overflow用户
提问于 2021-12-13 18:45:46
回答 2查看 75关注 0票数 1

这是我的第一个问题。如果我在询问或格式化方面做错了什么,请告诉我!

我的程序必须在控件中播放某些内容,直到播放完毕,然后继续处理另一项。

以下是整个功能:

代码语言:javascript
运行
复制
    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接受的方式读取此变量?也许让它成为只读变量?如果是这样的话,是怎么做的?

谢谢你,利亚姆

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-13 19:51:17

我找到了我的具体案子的答案。我使变量audioFileFinished成为静态变量。在任务中执行的方法现在位于与audioFileFinished相同的类中。我的功能现在看起来如下:

代码语言:javascript
运行
复制
    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));
    }

主类中的方法如下所示:

代码语言:javascript
运行
复制
    public static void PlayAfterThis(string path)
    {
        while (!audioFileFinished)
        {

        }
        localPlayer.URL = path;
    }

变量现在被初始化为public static bool audioFileFinished;

感谢@Etienne de Martel提出这样的建议:

,也许您的lambda甚至可以是包含该字段的类的一种方法。

票数 0
EN

Stack Overflow用户

发布于 2021-12-13 19:50:24

这里有一种方法,您可能想要更改的名称确实很糟糕:

代码语言:javascript
运行
复制
public class Completion : ICompletionNotification
{
    public bool IsCompleted { get; private set; }

    public void Complete() => IsCompleted = true;
}

public interface ICompletionNotification
{
    bool IsCompleted { get; }
}

调用代码会创建一个新的Completion,但是您的Play方法使用ICompletionNotification类型的参数。

代码语言:javascript
运行
复制
public void Play(AxWindowsMediaPlayer player, ICompletionNotification completion)

...and检查它的IsCompleted属性。

这样,调用方就可以创建一个Completion,并将其传递给Play()方法,后者将其转换为ICompletionNotification

代码语言:javascript
运行
复制
var completion = new Completion();
Play(player, completion);

调用方可以调用Complete()来指示它已经完成,但是接收方不能设置该属性。它只能读出来。

CancellationTokenCancellationTokenSource的工作方式基本相同。就像医生说的,

CancellationToken支持线程、线程池工作项或任务对象之间的协同取消。

代码语言:javascript
运行
复制
using CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;

// pass the token to some method, and then when it's done call
source.Cancel();

同样的想法。创建者可以取消它,但它传递的令牌只能用于查看操作是否已被取消。

我一开始并不推荐它,因为严格地说,你没有“取消”任何东西。但它是相同的概念,不需要定义一个新的类型。看到它的人会理解您正在做什么,或者可以查找现有的文档。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70339498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档