异步过程中,类中的部分数据不传递

chenyunlirui01 2022-07-06 10:24:04

请大神帮忙看看,有问题的程序是第二段,MethodAsync 传的参数 DataToProtocol类型包含两部分,一部分是ArrayList,一部分是string。经过await后,ArrayList的数据就全没了,数量为0,字符串还在。 这是什么情况?问问题原因是,await中执行的DoSomething中的ArrayList数据也没有,只有字符串。应该如何修改才能让DoSometing能让类的数据不丢失?

 

 public  static void  GetBack(DataToProtocol msg)
            {
                WriteToMySQL(msg);
                if (MQTTstart == false)
                {
                    MethodAsync(msg);//调用异步方法
                }
            }
public static async void MethodAsync(DataToProtocol msg)
            {
                MQTTstart = true;
               Console.WriteLine(msg.Data.Count.ToString()+","+msg.SQLTabelname+",111111");
                string str = await DoSomething(msg);
                Console.WriteLine(msg.Data.Count.ToString()+"," + msg.SQLTabelname+ ",222222222");
                MQTTstart =false;
            }
 static Task<string> DoSomething(DataToProtocol msg)
            {
               
                return Task<string>.Run(() =>
                {
                    GetBackFromProtocol(msg);
                    return "返回值";
                });
            }

 

...全文
420 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghui0380 2022-07-06
精选
  • 打赏
  • 举报
回复 1
 internal class DataToProtocol
    {
        public ArrayList Data { get; set; } =new ArrayList();
       
        public string SQLTabelname { get; set; }
    }

 DataToProtocol msg = new DataToProtocol()
            {
                Data = new ArrayList { 1, 2, 3 },
                SQLTabelname = "test"
            };

             MethodAsync(msg);

同样没有问题,上面这些代码都没有问题。如果说多线程并行,一会有一会没有,我大概猜需要看看这个DataToProtocol了,要是依赖staic静态字段就可以解释你这里出现的问题了

chenyunlirui01 2022-07-06
  • 举报
回复
@wanghui0380 本人纯新手, 没太明白。我就是定义了一个类。 我对static确实没理解啥意思。有时候程序提示让我static 我就static了,没考虑过为啥,大部分函数都是static的
chenyunlirui01 2022-07-08
  • 举报
回复
@wanghui0380 问题解决了,应该是arraylist不稳定导致的, 我换成字符串集合就OK了
cenxaoi 2022-11-15
  • 打赏
  • 举报
回复

多线程访问的对象为啥不加锁?class DataToProtoco

  • 打赏
  • 举报
回复

你提供的信息不足以发现你的bug,因此无法解决任何问题。不仅仅是你修改数据结构、修改参数类型,甚至你不修改数据结构而仅仅修改你测试所传的 ArrayList 数据,可能你也不调试分析抛出异常时的堆栈,而是给出了十足怪异的理论“解释”并且自己也能相信世界上有鬼,甚至千方百计推翻之前的比你得新代码成熟得多的老代码。由此我们看将来的开发环境,在一个小的业余开发团队里,如果不注重实际能力,团队将是非常危险的会彻底走偏。

仅从你的代码来看,你既然使用 async void MethodAsync(....) 来封装一个独立不需要等待的过程,它直接调用 GetBackFromProtocol(msg) 就可以了,这类代码使用一句 await Task.Yield() 语句就能通知 MethodAsync 方法在什么地方编织异步调用代码,而不需要另外封装一个 Task 去调用。当然我还是更注重理念,注重实际调试和测试,(相对)轻视编程语句。

  • 打赏
  • 举报
回复

实际去调试你的 bug,一个职业程序员不能说什么“ArrayList不稳定”这类话,顶多只能说“类型不明确,隐藏祸害”这类。你可以随便重新修改 DtaToProtocol 的数据结构,但是你却没能力调试 GetBackFromProtocol 方法,贴不出方法内部的调试截图,由此可见问题实际出处在于内部的堆栈!

例如有些人动不动就写 try......catch代码,即使不考虑异常处理所需要的巨大的性能缺失,也能从代码很容易看出其思维习惯,容易一眼看出可能已经丧失了调试开发能力,只能抄一些代码。“是否调试到位”是个最基础的程序员素质,是专业的开发者最注重的,是起决定性的。

这也是现在社会上很多所谓的“程序员培训基地”那类没有全面的软件的专业基础课的机构的弊害,培养出来的毕业生白花学费,没学到真的知识,仅被忽悠出了糊弄自己的激情。

chenyunlirui01 2022-07-06
  • 打赏
  • 举报
回复

img

wanghui0380 2022-07-06
  • 打赏
  • 举报
回复

使用下面对象,模拟调试,没有问题

internal class DataToProtocol
    {
        public List<int> Data { get; set; } = new List<int>();
       
        public string SQLTabelname { get; set; }
    }


chenyunlirui01 2022-07-06
  • 打赏
  • 举报
回复

img

public  static void  GetBack(DataToProtocol msg)
            {
                WriteToMySQL(msg);
                if (MQTTstart == false)
                {
                    MethodAsync(msg);//调用异步方法
                }
            }
            public static async void MethodAsync(DataToProtocol msg)
            {
                var msg2=msg;
                MQTTstart = true;
                Console.WriteLine(msg2.Data.Count.ToString()+","+msg2.SQLTabelname+",111111");
                string str = await DoSomething(msg2);
                Console.WriteLine(msg2.Data.Count.ToString()+"," + msg2.SQLTabelname+ ",222222222");
                MQTTstart =false;
            }
            static Task<string> DoSomething(DataToProtocol msg)
            {
               var msg1=msg;
                return Task<string>.Run(() =>
                {
                    GetBackFromProtocol(msg1);
                    return "返回值";
                });
            }
            public static void  GetBackFromProtocol(DataToProtocol msg)
            {

                var msg3 = msg;
                Console.WriteLine(msg3.Data.Count.ToString() + "," + msg3.SQLTabelname + ",33333333");
                System.Threading.Thread.Sleep(3000);
}
wanghui0380 2022-07-06
  • 打赏
  • 举报
回复

1.GetBackFromProtocol(msg);干了啥我们不知道
2.在有委托(闭包)的情况下,尽量不要直接使用方法形参,如果有异步动作直接使用形参,并行执行有可能会参数穿越,所以一般会使用方法内临时变量中介一下

var msg1=msg;
 return Task<string>.Run(() =>
                {
                    GetBackFromProtocol(msg1);
                    return "返回值";
                });


chenyunlirui01 2022-07-06
  • 举报
回复
@wanghui0380 谢谢,按你的方法,测试了一下,还是不太行。 感觉和GetBackFromProtocol干啥没关系,再帮忙看看,输出结果不是我想要的。我确实需要进入GetBackFromProtocol这个函数的数量是正确的。但是你可以看一下33333的前面的数量还是有为0 的情况。 帮忙指点一下!万分感谢!

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧