用于知道何时可以在新线程中调用方法的模式
本文关键字:线程 调用 方法 模式 何时可 新线程 用于 | 更新日期: 2023-09-27 18:22:22
我有一个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;
}
}
我想根据Instrument
属性对InstrumentedDevice
的实例进行分组,这样结果就是组的集合,其中每个设备都使用与其组中所有其他设备相同的仪器。
然后,我想为每组启动一个新线程,并并行执行测量。
看起来像这样:
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)
,但我不确定它是如何工作的。
public interface IDevice
{
string GroupBy {get;}
double Measure();
}
好的,我的第一个答案误解了这个问题。这是一个新的:
public interface IDevice
{
double Measure();
string ConcurrencyGroupName { get; }
}
每个设备都有一个新的"并发组名称"。惯例是,只有具有相同名称的设备才能并行处理。
所以你.group通过ConcurrencyGroupName和foreach组并行处理其项。
通过这种方式,设备决定是否要并行执行。进行处理的核心代码永远不需要修改。
InstrumentedDevice类只会返回仪器的名称或其ID作为ConcurrencyGroupName。其他实现也是可能的。
您需要将设备分为已插入指令的设备和未插入指令的:
var measurable = devices.OfType<InstrumentedDevice>().ToList();
var notMeasurable = devices.Except(measurable).ToList();
您可以独立处理这两个集合。
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)