2017-12-31 228 views
0

私は自分のコードを設計するための適切な方法を探しています。私はそのリストに入って(同じ基底クラスを持つ)デバイスの複数の異なるタイプを持っているようSmartCatDeviceBaseにC#Async(Factory)メソッドと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(); 
} 

は、タイプキャストが必要です:私は、次のようにして作成されたデバイスのリストを持っています。

問題は「自動接続」です。これは、デバイスが非同期ネットワーク接続を開く必要があります。コンストラクタ(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」に変換することはできません。 SELECT文でのawaitキーワードを使用して

...また

ことができていないか、または他の方法どのように適切設計ようなコードはありますか?コンストラクタで自動修正フラグを設定し、後で "外部から"接続するとOOPに違反しているように見えます:自動接続オプションがあるとき、私はそれをtrueに設定したときに自動作成することを期待します...

ありがとう!素晴らしい新年を!

+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