Oli*_*Oli 6 .net c# multithreading portable-class-library
我有一个应用程序,其中包含存储在a中的对象列表static ConcurrentBag.
UI有一个计时器,可以运行可以更新对象的方法ConcurrentBag.
只有一个线程(由计时器启动)将尝试更新这些对象.但是,此线程将枚举列表,然后更新项目.
同时,UI线程可以读取这些对象.
ConcurrentBag我正在做我想做的事情.所有业务逻辑都在一个单独的项目中,我现在需要将所有内容移植到iOS和Android.我正在使用Xamarin进行此操作,因此将业务逻辑转换为可移植类库.
虽然一切都我针对出现支持ConcurrentBag,当我试图访问它在PCL,System.Collections.Concurrent不可用.即使我只针对.net 4.5及以上+ windows存储应用程序(我用过ConcurrentBags的两个)
是否有其他替代方案ConcurrentBag或者我最好只为每个目标系统创建单独的项目?
小智 1
好吧,如果显而易见的方法行不通,您还有多种选择。首先,反编译 ConcurrentBag 并使用该代码。其次,就是想出一个替代品。据我估计,在您的具体情况下,您不一定需要 ConcurrentBag 的性能保证和订购问题......所以,这是一个适合您的账单的工作示例:
namespace Naive
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
public class ThreadSafeCollectionNaive<T>
{
private readonly List<T> _list = new List<T>();
private readonly object _criticalSection = new object();
/// <summary>
/// This is consumed in the UI. This is O(N)
/// </summary>
public ReadOnlyCollection<T> GetContentsCopy()
{
lock (_criticalSection)
{
return new List<T>(_list).AsReadOnly();
}
}
/// <summary>
/// This is a hacky way to handle updates, don't want to write lots of code
/// </summary>
public void Update(Action<List<T>> workToDoInTheList)
{
if (workToDoInTheList == null) throw new ArgumentNullException("workToDoInTheList");
lock (_criticalSection)
{
workToDoInTheList.Invoke(_list);
}
}
public int Count
{
get
{
lock (_criticalSection)
{
return _list.Count;
}
}
}
// Add more members as you see fit
}
class Program
{
static void Main(string[] args)
{
var collectionNaive = new ThreadSafeCollectionNaive<string>();
collectionNaive.Update((l) => l.AddRange(new []{"1", "2", "3"}));
collectionNaive.Update((l) =>
{
for (int i = 0; i < l.Count; i++)
{
if (l[i] == "1")
{
l[i] = "15";
}
}
});
}
}
}
Run Code Online (Sandbox Code Playgroud)