0

我正在编写一个读取串行端口数据的扩展。我在 BC14 OnPremis 上运行。这就是我所拥有的。全局变量,在客户端运行(显然串行端口不在服务器上,带有事件,因为我需要以某种方式接收数据。

var
    [RunOnClient]
    [WithEvents]
    Port: DotNet SerialPortA;

当端口上的数据可用时调用的触发器。它实际上被解雇了。

trigger Port::DataReceived(sender: Variant; e: DotNet SerialDataReceivedEventArgs)
var
    CurrPort: DotNet SerialPortA;
    BarText: DotNet String;
begin
    CurrPort := sender;
    BarText := CurrPort.ReadLine();
    Message(BarText);
end;

在 dotne.al 文件中,我有一个 SerialPort 类型的声明。由于某些原因,它会将名称与其他名称混淆,因此我不得不添加一个后缀来键入别名。所以现在我的类型叫做 SerialPort A

assembly("System")
{
    Version = '4.0.0.0';
    Culture = 'neutral';
    PublicKeyToken = 'b77a5c561934e089';

    type("System.IO.Ports.SerialPort"; "SerialPortA") { }
    type("System.IO.Ports.SerialDataReceivedEventArgs"; "SerialDataReceivedEventArgs") { }
    type("System.IO.Ports.SerialErrorReceivedEventArgs"; "SerialErrorReceivedEventArgs") { }
}

问题是调用CurrPort.ReadLine()失败并出现错误:

A call to System.Object.ReadLine failed with this message: The type of one or more arguments does not match the method's parameter type.

我尝试使用另一种方法Read。错误是一样的。它很可能与 Nav 将所有 dotnet 变量包装/解包为对象类型有关,但我不知道该怎么做。猜猜这里出了什么问题?

在事件日志中有错误描述

Server instance: N721
Category: Runtime
ClientSessionId: b6d2f654-0601-46b7-bd70-ae4fa637d422
ClientActivityId: 75ab980f-28d2-4a47-8d50-787c132c854c
ServerSessionUniqueId: cc752b06-1eab-43ed-8976-f1973da11ae5
ServerActivityId: fbc48c73-482c-4f84-87e3-4b3b1765dc5b
EventTime: 10/08/2020 06:29:21
Message   ObjectType: System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  MethodName: ReadLine
  BindingFlags: Instance, Public, InvokeMethod

ProcessId: 24200
Tag: 000010P
ThreadId: 199
CounterInformation: 

还有一个

Server instance: N721
Category: Runtime
ClientSessionId: b6d2f654-0601-46b7-bd70-ae4fa637d422
ClientActivityId: 75ab980f-28d2-4a47-8d50-787c132c854c
ServerSessionUniqueId: cc752b06-1eab-43ed-8976-f1973da11ae5
ServerActivityId: fbc48c73-482c-4f84-87e3-4b3b1765dc5b
EventTime: 10/08/2020 06:29:21
Message (NavNCLDotNetInvokeException): This message had personal data removed. The original may still be in transient telemetry. Find it using the transientTelemetryId.
ParentException: NavNCLDotNetInvokeException
A call to System.Object.ReadLine failed with this message: The type of one or more arguments does not match the method's parameter type.
ExceptionStackTrace:
   at Microsoft.Dynamics.Nav.Runtime.NavApplicationMethod.InvokeMethod(ITreeObject obj, String methodName, Object[] args, Boolean resolveHandler, Boolean throwOnNotFound)
   at Microsoft.Dynamics.Nav.Service.NSField.InvokeEventTriggerInternal(NavSession con, String eventName)
   at Microsoft.Dynamics.Nav.Service.NSField.InvokeEventTrigger(NavSession session, String eventName)
   at SyncInvokeInvokeEventTrigger(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.RunInTransactionCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.TransientErrorRetryCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.ErrorMappingCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
InnerException:
ParentException: TargetInvocationException
ExceptionStackTrace:
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Dynamics.Nav.Runtime.NavApplicationMethod.InvokeMethod(ITreeObject obj, String methodName, Object[] args, Boolean resolveHandler, Boolean throwOnNotFound)
InnerException:
RootException: NavNCLDotNetInvokeException
A call to System.Object.ReadLine failed with this message: The type of one or more arguments does not match the method's parameter type.
ExceptionStackTrace:
   at Microsoft.Dynamics.Nav.Types.NavAutomationHelper.GetMethodInfo(String methodName, Type objectType, BindingFlags binding, ParameterModifier[] modifier, Object[] arguments, Type[] referenceTypes)
   at Microsoft.Dynamics.Nav.Runtime.NavDotNet.Invoke[T](String methodName, UInt32 methodIndex, BindingFlags flags, ParameterModifier modifier, Type[] referenceTypes, Object[] arguments)
   at Microsoft.Dynamics.Nav.Runtime.NavDotNet.InvokeMethod[T](Boolean isStatic, String methodName, UInt32 methodIndex, Object[] arguments)
   at Microsoft.Dynamics.Nav.BusinessApplication.Page1057905.Porta58a58DataReceived_Scope.OnRun()
   at Microsoft.Dynamics.Nav.Runtime.NavMethodScope.Run()
   at Microsoft.Dynamics.Nav.BusinessApplication.Page1057905.Porta58a58DataReceived(NavVariant sender, NavDotNet e)
CallerStackTrace:
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.ErrorMappingCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.PushPopCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationTracer.TraceScopeCombinator(Category telemetryCategory, ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass10_0.<PerformanceCounterCombinator>b__0()
   at Microsoft.Dynamics.Nav.Runtime.NavPerformanceCounterSetter.UpdatePerformanceCountersWithAverageServiceOperationDuration(Stopwatch stopWatch, Action action)
   at Microsoft.Dynamics.Nav.Runtime.NavPerformanceCounterSetter.UpdatePerformanceCountersWithAverageServiceOperationAction(Action action, NavSession session)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.PerformanceCounterCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.InitClientTelemetryIdsCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.TlsClearCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
   at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
   at System.ServiceModel.Dispatcher.MessageRpc.Wrapper.Resume(Boolean& alreadyResumedNoLock)
   at System.ServiceModel.Dispatcher.ThreadBehavior.ResumeProcessing(IResumeMessageRpc resume)
   at Microsoft.Dynamics.Nav.Runtime.NavSynchronizationContext.<>c__DisplayClass1_0.<ClearThreadLocalStorageDelegate>b__0(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()


ProcessId: 24200
Tag: 00000HC
ThreadId: 199
CounterInformation: 
4

1 回答 1

0

我没有要测试的串行端口,所以这是我的首要任务。

您可能需要将变体转换为正确的类型:

trigger Port::DataReceived(sender: Variant; e: DotNet SerialDataReceivedEventArgs)
var
    Type: DotNet Type;
    Convert: DotNet Convert;
    CurrPort: DotNet SerialPortA;
    BarText: DotNet String;
begin
    // This check is just best pratice, but not needed in this case as we know sender is a SerialPort.
    if not sender.IsDotNet() then
      exit;

    Type := GetDotNetType(sender);
    CurrPort := Convert.ChangeType(sender, Type);
    BarText := CurrPort.ReadLine();
    Message(BarText);
end;
于 2020-10-28T09:09:48.277 回答