Closed dubeg closed 3 years ago
Hi, You can check the results of your call to CreateMonitoredItemsAsync. There is a Result for every element of ItemsToCreate.
var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);
for (int i = 0; i < itemsRequest.ItemsToCreate.Length; i++)
{
var req = itemsRequest.ItemsToCreate[i];
var res = itemsResponse.Results[i];
if (StatusCode.IsBad(res.StatusCode))
{
Console.WriteLine($"Unable to subscribe to req.ItemToMonitor.NodeId}. {StatusCodes.GetDefaultMessage(res.StatusCode)}");
}
}
OnError is triggered when the channel's internal loop that is calling PublishAsync raises an Exception. For instance, PublishAsync can raise a ServiceResultException with a status code 0x80850000 "Timeout occurred while processing the request." The channel may still be in Opened state at this point. You can call channel.Fault(ex) to cause the channel to change to Faulted state. You can call channel.AbortAsync().Wait() to change to the Closed state.
Hi @awcullen, thank you for your help. It seems the Opc Ua server I'm coding against (BR Automation) isn't returning a correct CreateMonitoredItemsReponse when the nodeIds don't exist. Ah well.
Is AbortAsync().Wait() in onNext(...) really safe?
Oh, I think I'll use channel.Fault(..)
if StatusCode is InvalidNodeId in onNext(..)
instead, based on what you said in the other thread.
Abort disposes the channel without communicating to the server ( which probably has closed it's session anyway)
Just to note, calling Fault on the channel in onNext doesn't trigger channel.Faulted. I'll to read the src code a bit to understand how it all works :^)
About subscriptions:
CreateMonitoredItemsAsync
is invalid/doesn't exist, instead of checking later duringOnNext
ofchannel.Subscribe(OnNext, OnError)
?OnNext
if the statusCode of an item is bad?channel.AbortAsync().Wait()
?onError
inchannel.Subscribe(onNext, onError)
?Also, it's kind of a bummer that StatusCodes are members of a static class instead of a proper enum, because then I could use its name to display in a log message. If it were an enum, I could do
statusCode.ToString()
to getBadNodeIdInvalid
, for example.