在C#5中异步调用相同的方法是否安全

时间:2013-09-18 15:38:58

标签: c# asynchronous

如果您能让我知道多次异步调用相同方法的意见,我将不胜感激。我更感兴趣的是了解这项活动的安全性。我在这里发布了一个控制台代码,其中包含一个我异步调用四次的方法,它运行良好。到目前为止,我没有注意到任何打嗝。但我想确定。请使用以下代码:

public class OneMethodCalledServeralTimes
    {
        protected async Task<bool> DoSomeWork(Values values, int whenItIsCalled, string description)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();

            await Task.Delay(values.Value);

            Console.WriteLine("{0} Completed in {1} and this was called: {2}",description, stopWatch.ElapsedMilliseconds, whenItIsCalled);

            return true;
        }

        public bool DoAllWork()
        {
            Console.WriteLine("=====================Started doing weekend Chores===================");
            var task1 = DoSomeWork(new Values { Value = 10000 }, 1, "First work to be done");
            var task2 = DoSomeWork(new Values {Value = 7000}, 1, "First work to be done");
            var task3 = DoSomeWork(new Values { Value = 4000 }, 2, "second work to be done");
            var task4 = DoSomeWork(new Values { Value = 1000 }, 3, "third work to be done");

            Task.WaitAll(task1, task2, task3, task4);

            Console.WriteLine("=====================Completed doing weekend Chores===================");

            return true;
        }

    }

以下是调用上述调用的控制台应用程序:

static void Main(string[] args)
        {
            //var weekend = new HomeWork().DoAllWork();

            Console.WriteLine("############################Using proper methods#############################");


            var workToBeDone= new OneMethodCalledServeralTimes().DoAllWork(); //Passing parameters and the most successful one

            Console.WriteLine("It took the entire four mothod {0} seconds to finish", stopewach.ElapsedMilliseconds/1000.0);

            Console.ReadKey();
        }

我也非常欢迎任何关于玉米的简洁观点以及多次异步调用相同方法的优点

1 个答案:

答案 0 :(得分:8)

这取决于方法 - 但它肯定不是不安全。编译器生成的状态机中没有任何内容引入问题。但是,如果您的异步方法使用共享状态,则适用常规警告。例如,您不希望同时调用此多个线程:

static Task DoBadThingsAsync(List<string> list)
{
    await Task.Delay(500);
    list.Add("Hello!");
}

...因为如果任何线程执行写操作(没有同步),List<T>在多线程环境中使用是不安全的。

需要注意的一点是,如果你有预期在“单线程同步上下文”中使用的异步方法(例如WPF或WinForms应用程序中的UI线程),那么你不必担心关于线程的安全性 - 但你需要担心一般的并发性,因为这两种方法的调用都可以同时“生效”。