C#流API的锁定和线程安全

时间:2018-07-05 23:13:39

标签: c# .net multithreading locking ienumerable

可能是一个相当简单的问题,但是我想知道使代码线程安全的最佳实践。

我在多线程环境中使用外部非线程安全API。

它返回一个IEnumerable<ApiDto>。 然后,我将每个ApiDto映射到应用程序的DTO: MyDto

如何确保代码是线程安全的?

例如:

这是我的从API获取项目的类

public class ApiRepo
{
    private IApi api;
    public ApiRepo()
    {
        api=new Api("url");
    }
    public IEnumerable<MyDto> GetItems()
    {
        var apiDtos = api.GetNonThreadSafeItems();
        foreach(var apiDto in apiDtos)
        {
           var myDto = new MyDto(apiDto.Name);  
           yield return myDto;
        }

    }

}

这是我的客户应用程序。 创建了多个Client实例,并从API检索了数据。

public class Client
{
    public void GetData()
    {
        var items = new ApiRepo().GetItems().ToList();
        Console.WriteLine(items.Count);
    }
}

我应该在Client.GetData()中放置一个锁,还是有什么更好的方法来使代码具有线程安全性?

1 个答案:

答案 0 :(得分:-1)

API是“非线程安全的”,意味着它基于某种资源资源同步机制运行。因此,为了从API获得正确的结果,您需要确保一次只有一个线程调用它。根据您的样本,最简单的方法是

public class ApiRepo
{
    static private object theLock = new object();
    private IApi api;

    public ApiRepo()
    {
        api=new Api("url");
    }

    public IEnumerable<MyDto> GetItems()
    {
        IEnumerable<ApiDto> apiDtos = null;
        lock(theLock)
        {
            apiDtos = api.GetNonThreadSafeItems();
        }
        foreach(var apiDto in apiDtos)
        {
           var myDto = new MyDto(apiDto.Name);  
           yield return myDto;
        }
    }
}