我有一个Device
界面:
public interface IDevice
{
double Measure();
}
实现该界面的一些类具有测量工具:
public class InstrumentedDevice : IDevice
{
public MeasuringInstrument Instrument { get; set; }
public double Measure()
{
if (Instrument != null)
return Instrument.DoMeasuring();
return 0;
}
}
我想根据InstrumentedDevice
属性对Instrument
的实例进行分组,以便结果是一组组合,其中每个设备使用与其中所有其他设备相同的工具基。
然后,我想为每个组开始一个新线程并同时执行测量。
这看起来像这样:
public void MeasureAllDevices(IEnumerable<InstrumentedDevice> devices)
{
var groups = devices.GroupBy(d => d.Instrument);
foreach (var gr in groups)
{
var bgw = new BackgroundWorker();
bgw.DoWork += (s, e) =>
{
foreach (var device in gr)
{
device.Measure();
}
};
bgw.RunWorkerAsync();
}
}
问题是我没有将InstrumentedDevice
的集合作为MeasureAllDevices
的参数。我得到了IDevice
:
public void MeasureAllDevices(IEnumerable<IDevice> devices)
{
}
我的问题是:我可以遵循一个模式来解决我的问题吗?并非所有设备都具有MeasuringInstrument
,并且某些设备可能有不同的方法来确定它们是否可以并行测量。
我想在IDevice
界面添加一些内容,例如CanBeMultiThreadedWith(IDevice other)
,但我不确定这是如何运作的。
答案 0 :(得分:1)
public interface IDevice
{
string GroupBy {get;}
double Measure();
}
答案 1 :(得分:1)
好的,我的第一个回答误解了这个问题。这是一个新的:
public interface IDevice
{
double Measure();
string ConcurrencyGroupName { get; }
}
每个设备都获得一个新的“并发组名称”。惯例是只有具有此名称相同的设备才能并行处理。
所以你.GroupBy ConcurrencyGroupName和foreach组你并行处理它的项目。
这样设备决定是否要并行执行。执行处理的中心代码永远不必修改。
您的InstrumentedDevice类只会返回乐器的名称或其ID ConcurrencyGroupName。其他实现也是可能的。
答案 2 :(得分:0)
您需要将设备拆分为已检测的设备和非设备的设备:
var measurable = devices.OfType<InstrumentedDevice>().ToList();
var notMeasurable = devices.Except(measurable).ToList();
您可以单独处理这两个集。
答案 3 :(得分:0)
public static MeasuringInstrument Instrument(this IDevice device)
{
if (device is InstrumentedDevice)
{
return (device as InstrumentedDevice).Instrument;
}
return null;
}
var groups = devices.GroupBy(d => d.Instrument());
foreach (var gr in groups)