问题描述
我正在编写一个读取串行端口数据的扩展程序。我正在BC14 OnPremis上运行。 这就是我所拥有的。在客户端运行的全局变量(显然Serioal端口不在服务器上,带有事件,因为我需要以某种方式接收数据。
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
Counter@R_487_4045@ion:
还有一个
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[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__displayClass28_1.<Combine>b__1(NSServiceBase serviceInstance,Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.TransientErrorRetryCombinator(ServiceOperation innerOperation,Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.ErrorMappingCombinator(ServiceOperation innerOperation,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,CultureInfo culture)
at Microsoft.Dynamics.Nav.Runtime.NavApplicationMethod.InvokeMethod(ITreeObject obj,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,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,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,Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.PushPopCombinator(ServiceOperation innerOperation,Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationTracer.TraceScopeCombinator(Category telemetryCategory,ServiceOperation innerOperation,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,Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.InitClientTelemetryIdsCombinator(ServiceOperation innerOperation,Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.TlsClearCombinator(ServiceOperation innerOperation,Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.Invoke(Object instance,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,Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.dispatch()
ProcessId: 24200
Tag: 00000HC
ThreadId: 199
Counter@R_487_4045@ion:
解决方法
我没有要测试的串行端口,所以这是我的首要考虑。
您可能需要将变体转换为正确的类型:
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;