相关疑难解决方法(0)

异步/等待代码中的竞争条件

我只是想知道下面的代码中是否出现竞争条件:

int readingFiles;
async Task<string> ReadFile (string file)
{    
    ++readingFiles;

    var text = await Stream.ReadFileAsync(file);

    --readingFiles;

    return text;
}
Run Code Online (Sandbox Code Playgroud)

如果线程池线程执行ReadFile方法,则readFiles将由两个不同的线程访问,而readingFiles变量不受任何同步惯用法的保护.

这意味着对于执行"--readingFiles"的其他线程,readFiles的第一次更新不应该是可见的.但是,在"--readingFiles"之后,我从未见过readFiles等于-1.我检查同一个线程是否使用Thread.CurrentThread执行++和 - 操作.在大多数情况下,它不是同一个线程,我仍然没有看到readingFiles为-1.

即使存在竞争条件且readingFiles不易变,为什么我不能看到这种竞争条件的影响?

c# multithreading asynchronous race-condition async-await

9
推荐指数
2
解决办法
3496
查看次数

使用 async/await 时是否需要使字段线程安全?

有时我会遇到访问对象字段的异步/等待代码。例如,无状态项目中的这段代码

private readonly Queue<QueuedTrigger> _eventQueue = new Queue<QueuedTrigger>();
private bool _firing;

async Task InternalFireQueuedAsync(TTrigger trigger, params object[] args)
{
    if (_firing)
    {
        _eventQueue.Enqueue(new QueuedTrigger { Trigger = trigger, Args = args });
        return;
    }

    try
    {
        _firing = true;

        await InternalFireOneAsync(trigger, args).ConfigureAwait(false);

        while (_eventQueue.Count != 0)
        {
            var queuedEvent = _eventQueue.Dequeue();
            await InternalFireOneAsync(queuedEvent.Trigger, queuedEvent.Args).ConfigureAwait(false);
        }
    }
    finally
    {
        _firing = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,则await **.ConfigureAwait(false)表明在此之后执行的代码await不一定必须在相同的上下文中执行。所以while这里的循环可以在 ThreadPool 线程上执行。我不明白是什么确保_firing_eventQueue字段同步,例如什么在这里创建锁/内存栅栏/屏障?所以我的问题是;我是否需要使字段线程安全,或者 …

c# multithreading asynchronous task-parallel-library async-await

4
推荐指数
1
解决办法
1万
查看次数