2017-12-31 198 views
0

코드를 디자인 할 적절한 방법을 찾고 있습니다. 나는 장치 목록을 생성 된 다음과 같은 방법이 있습니다C# Async (Factory) Methods & LINQ

public void LoadDevices() 
{ 
    using (XmlReader xmlRdr = new XmlTextReader(deviceConfigPath)) 
     deviceList = (from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device") 
       where (string)deviceElem.Attribute("type") == "mks247" 
       select (SmartCatDeviceBase)new mks247Device(
        (string)deviceElem.Attribute("ip"), 
        (string)deviceElem.Attribute("name"), 
        (string)deviceElem.Attribute("id"), 
        (bool)deviceElem.Attribute("autoconnect") 
        )).ToList(); 
} 

타입 캐스팅 내가 그리스트에가는 (같은베이스 클래스) 장치의 많은 다른 유형이 같은 SmartCatDeviceBase에하는 것이 필요하다.

이제 문제는 "자동 연결"입니다. 장치에서 비동기 네트워크 연결을 열어야합니다.이 연결은 생성자 (as Stephen Cleary states here)에서 수행하면 안됩니다.

private async Task<SmartCatDeviceBase> Createmks247DeviceAsync(string host, string name, string id, bool autoconnect = true) 
    { 
     mks247Device dev = new mks247Device(host, name, id); // Now without the autoconnect, that shouldn't be in the constructor. 
     // Connect. 
     if (autoconnect) 
     { 
      bool connected = await dev.ConnectAsync(); 
      // Begin to poll for data. 
      dev.BeginPolling(); 
     } 
     return dev; 
    } 

그래서 질문은 다음과 같습니다 : 그 코드가 작동 할 수있는 방법을

그러므로 나는 공장 같은 것은 어떤 종류의에 의존하고 싶어? 새로운 mks247Device을 Createmks247DeviceAsync를 사용하는 대신 때문에() 내 LINQ 코드에서 작동하지 않을 것입니다 :

이 유형 "System.Threading.Tasks.Task"가 "SmartCatDeviceBase"변환 할 수 없습니다. 선택 문에 await를 키워드를 사용

... 또한

수 없습니다 또는 다른 방법으로 어떻게 제대로 디자인과 같은 코드가있다? 생성자에서 자동 고침 플래그를 설정하고 나중에 "외부에서"연결하면 OOP를 위반하는 것 같습니다. 자동 연결 옵션이있는 경우 자동 설정을 시도 할 때 자동 생성을 거부합니다 ...

미리 감사드립니다. ! 멋진 새해를 보내십시오!

+0

모든 작업을 선택한 다음 'Task.WhenAll'을 연결하기를 기다리는 중입니다. – Nkosi

답변

0

메소드를 비동기로 변환하십시오.

Linq를 사용하여 모든 작업을 선택한 다음 Task.WhenAll을 기다려 연결하십시오.

public async Task LoadDevicesAsync() { 
    using (XmlReader xmlRdr = new XmlTextReader(deviceConfigPath)) { 
     var getdeviceListTasks = (from deviceElem in XDocument.Load(xmlRdr).Element("devices").Elements("device") 
       where (string)deviceElem.Attribute("type") == "mks247" 
       select Createmks247DeviceAsync(
        (string)deviceElem.Attribute("ip"), 
        (string)deviceElem.Attribute("name"), 
        (string)deviceElem.Attribute("id"), 
        (bool)deviceElem.Attribute("autoconnect") 
        )); 
     var devices = await Task.WhenAll(getdeviceListTasks); 
     deviceList = devices.ToList(); 
    } 
} 
+0

감사합니다. 이것은 완벽한 해결책으로 밝혀졌습니다. – AndreasN