C#中的异步方法WhenAll问题

3

最近我遇到了调用异步方法的问题。 以下是代码:

ClassA storage = new ClassA();// this is member of the class

async Task<ClassA> InitClassAObject(){ // async method of the class


    List<Task> taskList = new List<Task>(); // create list task
        taskList.Add(Func1());
        taskList.Add(Func2());
        taskList.Add(Func3());            

        await Task.WhenAll(taskList.ToArray()); // wait for all task done

        return storage; // <--- this line never be hit
 }

 async Task Func1(){
        await Task.Run(() =>{
          //update property A of storage
          //example storage.A = GetDataFromSomeWhere();
   });
 }

 async Task Func2(){
        await Task.Run(() =>{
          //update property B of storage
          //example storage.B = GetDataFromSomeWhereElse();
   });
 }
 ...

问题1:方法InitClassAObject()从不返回。在"return never"处设置断点。

问题2:如果我调用多个异步方法并且它们更新ClassA对象的不同属性,这样做是否安全?

我已经搜索了解决方案,但仍未找到。谢谢。


2
也许所有的任务都没有完成? - Magnus
2
你调试了 Func1Func2Func3 的功能吗?如果 return storage 永远不会被触发,那么很可能是因为其中至少一个任务没有完成。 - René Vogt
感谢您的评论。当我同步调用Func1(); Funct2();时,这个方法曾经有效。然后我切换到这种方法,它不再起作用了。那么我认为这些函数没有问题。但是我会再次验证它们以确保。 - Đức Toàn Dương
1
@ĐứcToànDương 听起来像是你的任务互相等待。 - user3292642
1
你从 Func1()Func2() 返回什么对象? - Denis Krasakov
抱歉各位,我发现我的一个 funct() 函数因为我的输入错误而抛出了异常。现在当我在函数中添加 try-catch 块时它可以工作了。但是,有人能告诉我关于问题2吗? - Đức Toàn Dương
2个回答

2

因为使用相同的源(对象),所以函数可能会导致死锁?请不要使用相同的对象并查看结果。


谢谢你的回答。我发现我的代码之一未能完成。顺便说一下,虽然它现在可以工作,但我仍然担心异步修改对象的不同属性可能会引起问题。 - Đức Toàn Dương

2
关于问题2:更新不同的属性是安全的。但是请记住,如果你在Task2中修改了SomeProperty并在Task1中读取它,结果将是不可预测的(Task1可能会在Task2写入之前或之后读取)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接