2016-05-26 6 views
0

Я разрабатываю, как лучше всего использовать DLL-библиотеки C#, используя Edgejs для узла.Обещание не завершаться при использовании Edge with Node

Одна из функций проксите в узле выглядит следующим образом (метод класса в машинописи):

readSettings(args: ReadSettingsParams) : Promise<response> { 
    let $engine = this; 
    var proxy = edge.func({ 
     assemblyFile: "C:\\Development\\IAStash\\GLReport\\GLReport\\bin\\x64\\Debug\\GLReportEngine.dll", 
     typeName: "GLReportEngine.edgeGLReport", 
     methodName: "readSettings" 
    }); 
    return new Promise<response>(function (resolve, reject) { 
     args.instance = $engine.instance; 
     proxy(args, function(error, result) { 
      if (error) { 
       reject(error); 
      } else { 
       resolve(result); 
      } 
     }); 
    }); 
} 

Когда моя сложная задача в C# является синхронной, все работает, как ожидалось, но когда я перехожу ядро ​​C# функция в задаче:

return await Task.Run<object>(() => { do some stuff }); 

Когда я использую выше рисунок, линия решительность (результат) будет удар, результат правильно в окне просмотра, но любые .then или Q.all структуры, которые состоят сделать не отвечать на решение (результат), выполненное.

Я обнаружил, что если я console.log ("x"); до того, как обратный вызов прокси-сервера вернется, мои структуры .then и Q.all срабатывают, как ожидалось. то есть эта версия работает:

readSettings(args: ReadSettingsParams) : Promise<response> { 
    let $engine = this; 
    var proxy = edge.func({ 
     assemblyFile: "C:\\Development\\IAStash\\GLReport\\GLReport\\bin\\x64\\Debug\\GLReportEngine.dll", 
     typeName: "GLReportEngine.edgeGLReport", 
     methodName: "readSettings" 
    }); 
    return new Promise<response>(function (resolve, reject) { 
     args.instance = $engine.instance; 
     proxy(args, function(error, result) { 
      console.log("GLReportProxy.readSettings proxy returns, Err = " + (!!error)); 
      if (error) { 
       reject(error); 
      } else { 
       resolve(result); 
      } 
     }); 
    }); 
} 

Моя C# рутина в этом случае читает файл XML, десериализует его и возвращает его:

public Task<object> readSettings(object args) 
    { 
     if (args != null && typeof(System.Dynamic.ExpandoObject).IsAssignableFrom(args.GetType())) 
     { 
      var argdict = (IDictionary<string, object>)args; 
      if (argdict.ContainsKey("report")) 
      { 
       reportsettingsfile = argdict["report"].ToString(); 
      } 

      return Task.Run<object>(
       () => { 
        if (File.Exists(reportsettingsfile)) 
        { 
         var xser = new XmlSerializer(typeof(ReportSettings.report)); 
         string settingstext = File.ReadAllText(reportsettingsfile); 
         using (var tre = new StringReader(settingstext)) 
         { 
          reportSettings = (ReportSettings.report)xser.Deserialize(tre); 
         } 
         return new { result = true, model = reportSettings }; 
        } 
        else 
        { 
         return new { result = false, error = "File not found" }; 
        } 
       }); 
     } else 
     { 
      return Task.FromResult<object>(new { result = false, error = "Expected (input) object but can't read it." }); 
     } 
    } 

Это довольно просто. Я полагаю, что у меня проблемы с использованием async/await, что вызывает проблемы в узле. Если честно, я ожидал, что обещания будут надежными. Могут возникнуть проблемы с использованием Typcript, Node, Edge, Promises, Q.

Если кто-нибудь знает, что происходит, и почему регистрация на консоли устраняет проблему. Буду признателен за любую помощь!

Марк

+0

Похоже, что это известная проблема в краю: https://github.com/tjanczuk/edge/issues/325 Я думаю, что вопрос в том, как можно разблокировать потоки без регистрации? –

ответ

0

Я обнаружил, что это проблема, когда есть http.listener и C# край прокси обратного вызова в том же процессе. Могут быть и другие комбинации, но некоторая взаимосвязь между библиотеками является основной причиной.

Поскольку эта проблема не разрешена в соответствии с edgejs, метод console.log является хорошим способом обхода, особенно если вы не возражаете написать какое-то полезное сообщение в окне журнала.

console.log является хорошим обходным решением, но я хотел что-то молчаливое. Я заметил, что консоль внутренне имеет _stdout. Если вы выполните console._stdout.write (''); вы получаете тихую разблокировку. в TypScript вы должны сделать (консоль как любая) ._ stdout.write ('');.

Я делаю это при входе в обратный вызов прокси-сервера. например

readSettings(args: ReadSettingsParams) : Promise<response> { 
    let $engine = this; 
    var proxy = edge.func({ 
     assemblyFile: "C:\\Development\\IAStash\\GLReport\\GLReport\\bin\\x64\\Debug\\GLReportEngine.dll", 
     typeName: "GLReportEngine.edgeGLReport", 
     methodName: "readSettings" 
    }); 
    return new Promise<response>(function (resolve, reject) { 
     args.instance = $engine.instance; 
     proxy(args, function(error, result) { 
      (console as any)._stdout.write(''); 
      //console.log("GLReportProxy.readSettings proxy returns, Err = " + (!!error)); 
      if (error) { 
       reject(error); 
      } else { 
       resolve(result); 
      } 
     }); 
    }); 
} 

Очевидно, что вы можете зарегистрировать что-то, как указано в комментарии.