Bil*_*eer 6 c# multithreading asynchronous win-universal-app iot
我需要在 Windows 通用应用程序中编写一个方法来写入 SD 卡。在下面的方法中,如何确保两个线程不会尝试同时写入同一个文件?
public async void WriteToCard(string strFileName, IEnumerable<string> listLinesToWrite)
{
IStorageItem item = await folder.GetItemAsync(strFileName);
StorageFile file = (StorageFile)item;
await Windows.Storage.FileIO.WriteLinesAsync(file, listLinesToWrite);
}
Run Code Online (Sandbox Code Playgroud)
您可以保留一个带有 的映射,将ConcurrentDictionary每个文件映射到SemaphoreSlim. 然后,根据您要写入的文件位置获取每个信号量:
private ConcurrentDictionary<string, SemaphoreSlim> fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
public async Task WriteToCardAsync(string strFileName, IEnumerable<string> listLinesToWrite)
{
var semaphoreSlim = fileLocks.GetOrAdd(strFileName, new SemaphoreSlim(1, 1));
await semaphoreSlim.WaitAsync();
try
{
IStorageItem item = await folder.GetItemAsync(strFileName);
StorageFile file = (StorageFile)item;
await Windows.Storage.FileIO.WriteLinesAsync(file, listLinesToWrite);
}
finally
{
semaphoreSlim.Release();
}
}
Run Code Online (Sandbox Code Playgroud)
旁注 - 使用async Task而不是async void. 我还将Async后缀添加到方法中。
假设不会有大量文件名,您可以使用 aConcurrentDictionary将文件名与锁关联 - 否则,字典大小可能会无限增长。
private readonly locks = new ConcurrentDictionary<string, AsyncLock>();
public async void WriteToCard(string strFileName, IEnumerable<string> listLinesToWrite)
{
var lock = locks.GetOrAdd(strFileName, () => new AsyncLock());
using (await lock.LockAsync())
{
IStorageItem item = await folder.GetItemAsync(strFileName);
StorageFile file = (StorageFile)item;
await Windows.Storage.FileIO.WriteLinesAsync(file, listLinesToWrite);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7357 次 |
| 最近记录: |