首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#从其他线程更改对象

C#从其他线程更改对象
EN

Stack Overflow用户
提问于 2012-06-14 22:00:29
回答 2查看 579关注 0票数 1

我正在创建一个可以通过语音使用的议程。此外,还有一个虚拟助理(VA),他给出反馈,并有一些人工智能来获得并保持良好的日常节奏。

现在的情况是,我有一个公共静态列表议程。

Agenda是一个抽象类,目前有9种不同的议程类型。这是程序员的数据核心。这包含了程序员需要知道的所有内容。

主线程包含GUI和人们可能期望的议程的可用性。

虚拟助手需要做的所有事情都是在不同的线程中完成的。这主要是检查议程,并问一些问题,如果人们想在议程上做任何事情。

棘手的部分是当我还想从某些逻辑(可以说是添加人工智能)将一些事情添加到议程中时,比如日常用餐。这来自VA线程,但我不能从那里更改Agenda.agenda并得到一个错误,说明集合已被修改。

我试过锁定它,但没有区别。

将餐食添加到今天:

代码语言:javascript
运行
复制
    public void Meal()
    {
        DateTime date = DateTime.Now;

        DateTime morning = date;
        morning = morning.ChangeTime(8, 0, 0, 0);

        DateTime afternoon = date;
        afternoon = afternoon.ChangeTime(12, 0, 0, 0);

        DateTime evening = date;
        evening = evening.ChangeTime(16, 30, 0, 0);

        if (!meal && date.Hour < 21)
        {
            if(date.DayOfWeek == DayOfWeek.Wednesday)
                toAdd.Add(new Task("broodbuffet", morning, new Dictionary<DateTime, bool>()));
            else
                toAdd.Add(new Task("ontbijt", morning, new Dictionary<DateTime, bool>()));
            toAdd.Add(new Task("lunch", afternoon, new Dictionary<DateTime, bool>()));
            toAdd.Add(new Task("diner", evening, new Dictionary<DateTime, bool>()));

            meal = true;
        }

        if (date.Hour > 22)
            meal = false;
    }

在我用VA做基础知识的班级里:

代码语言:javascript
运行
复制
ai.Meal();
UpdateAgenda();

要在线程中更新的方法:

代码语言:javascript
运行
复制
private void UpdateAgenda()
    {
        if (ai.GetToAdd().Count != 0)
        {
            Agenda.agenda.AddRange(ai.GetToAdd());
        }
    }

和锁定:

代码语言:javascript
运行
复制
private void UpdateAgenda()
    {
        if (ai.GetToAdd().Count != 0)
        {
            lock (Agenda.agenda)
            {
                Agenda.agenda.AddRange(ai.GetToAdd());
            }
        }
    }

那么简而言之,如何从VA线程将议程项目添加到我的议程中?

EN

回答 2

Stack Overflow用户

发布于 2012-06-14 22:16:53

使用锁定是正确的,但您不能只在更改属性时锁定。

锁不会锁定属性,它会锁定代码,因此您必须在使用该属性的所有代码周围设置一个锁,以便更改该属性的代码可以锁定从该属性读取的代码。

票数 0
EN

Stack Overflow用户

发布于 2012-06-15 12:38:57

特别是对于您得到的错误("Collection changed"),也许您使用foreach循环迭代了Agenda对象中的任何集合?当一个集合在foreach循环中改变时(在您的例子中,是由另一个线程改变的),IEnumerator.MoveNext就会抛出这样的错误。如果这就是问题所在,您需要锁定整个foreach循环。

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

https://stackoverflow.com/questions/11034758

复制
相关文章

相似问题

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