登录异步方法

时间:2016-01-15 11:33:22

标签: c# asynchronous

我有这个程序,它有两个异步方法,它们想在同一时间在日志中写一些东西。

class Program
{
    private const string LOG_FILE = "Log.txt";
    private static object _Lock = new object();

    static void Main(string[] args)
    {
        var p = new Program();

        new Task(p.Func1).Start();
        new Task(p.Func2).Start();

        Console.ReadKey();
    }

    private async void Func1()
    {
        for (int i = 0; i < 10; i++)
            this.Log("1");
    }

    private async void Func2()
    {

        for (int i = 0; i < 10; i++)
            this.Log("2");
    }

    private void Log(string msg)
    {
        lock(_Lock)
        {
            File.AppendAllText(LOG_FILE, msg);
        }
    }
}

输出是这样的“11222222222211111111”,可能会改变。为什么输出不是“12121212121212121212”?

如果我是正确的,那么Func2将等到Func1将“1”写入日志文件。然后Func2将写入“2”并且Func1将等待。

1 个答案:

答案 0 :(得分:2)

异步并不意味着你交替运行。这意味着你给任何人选择运行。 (同样来自抓住锁)

有点像这样

  • 任务1开始,找到锁并把它拿走
  • 然后在x毫秒之后它被抢占(https://en.wikipedia.org/wiki/Preemption_(computing)),经常由于文件访问而发生,但它也会在一定时间后发生,让操作系统有机会做其他事情。
  • 现在任务2启动有机会运行。任务2发现任务1仍然具有锁定并等待。
  • 任务1继续并释放锁定,然后可能再次被抢占。
  • 然后第一个被唤醒再次获取锁定的线程(可能是其中一个线程)该线程将获得下一个锁定。

结果是任何线程都可以以任何顺序登录。或者1个线程在其他线程有机会运行之前完成所有工作。

正如Yacoub指出的那样,任务1&amp; 2在不同的核心上运行。但锁定原则仍然适用。拥有它的第一个线程将执行。根据算法(通常在OS或甚至处理器/程序集级别),锁定语句可能没有公平/排队机制。

相关问题