trying to receive data about received and sent bytes in every connection, that createt at the PC. I'm using WinRT UWP windows 10app, namespace Windows.Networking.Connectivity.
Here is my metode
private ulong BytesReceivedCheck(ConnectionProfile connectionProfile)
{
var currentDate = DateTime.Now;
var startDate = DateTime.Now.AddYears(-1);
//Get the ConnectionProfile that is currently used to connect to the Internet
IAsyncOperation<IReadOnlyList<NetworkUsage>> LocalUsage = connectionProfile.GetNetworkUsageAsync(startDate, currentDate, DataUsageGranularity.Total, new NetworkUsageStates());
var networkUsages = LocalUsage.GetResults();
foreach (NetworkUsage networkUsage in networkUsages)
{
return networkUsage.BytesReceived;
}
return 0;
}
I'm giving this metode as a parameter to a object
ConnectionModel model = new ConnectionModel(BytesReceivedCheck(connectionProfile));
Here is my model
public class ConnectionModel : INotifyPropertyChanged
{
ulong bytesReceived;
public ulong BytesReceived
{
get
{
return this.bytesReceived;
}
set
{
if (this.bytesReceived != value)
{
this.bytesReceived = value;
this.RaisePropertyChanged();
}
}
}
public ConnectionModel(ulong bytesReceived)
{
this.BytesReceived = bytesReceived;
}
}
I'm receiving exceprion "method invoked in unexpected time" in line var networkUsages = LocalUsage.GetResults(); in my methode. I think problem with Async, pls give me correct example of this method. I'm a begginer so sorry for maybe dumb question.
Related
I'm trying to send a query with a location point to Azure Cosmos DB (MongoDB) and get the locations near that point.
I got most of the information from here. And I'm using Microsoft.Azure.Documents.Spatial;.
So far, I've tried many solutions of other older posts, and nothing has worked for me.
My class definition:
public class Place : INotifyPropertyChanged
{
[BsonId(IdGenerator = typeof(CombGuidGenerator))]
public Guid Id { get; set; }
Point _location;
[BsonElement("Location")]
public Point Location
{
get => _location;
set
{
if (_location == value)
return;
_location = value;
HandlePropertyChanged();
}
}
long _addedDate;
[BsonElement("AddedDate")]
public long AddedDate
{
get => _addedDate;
set
{
if (_addedDate == value)
return;
_addedDate = value;
HandlePropertyChanged();
}
}
void HandlePropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Mongo connection:
// APIKeys.Connection string is found in the portal under the "Connection String" blade
MongoClientSettings settings = MongoClientSettings.FromUrl(
new MongoUrl(APIKeys.ConnectionString)
);
settings.SslSettings =
new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 };
// Initialize the client
var mongoClient = new MongoClient(settings);
// This will create or get the database
var db = mongoClient.GetDatabase(dbName);
// This will create or get the collection
var collectionSettings = new MongoCollectionSettings { ReadPreference = ReadPreference.Nearest };
PlacesCollection = db.GetCollection<Place>(collectionName, collectionSettings);
Query:
var point = new Point(22, -5);
IMongoQueryable<Place> query = PlacesCollection.AsQueryable().Where(p => p.Location.Distance(point) < 30000);
return query.ToList();
I get the following error in return query.ToList():
Unhandled Exception:
System.InvalidOperationException:
{document}{Location}.Distance(value(Microsoft.Azure.Documents.Spatial.Point))
is not supported.
I don't understand what is not supported neither how to create the correct query for this. Any idea?
Edit:
Call Stack
0xE0 in XamFormsMaps.Core.Services.MongoService.GetPlacesNear at C:\Users\Role\source\repos\XamFormsMaps\XamFormsMaps\XamFormsMaps.Core\Services\MongoService.cs:84,13 C#
[External Code]
0x20 in XamFormsMaps.Core.Services.DatabaseService.GetPlacesNear at C:\Users\Role\source\repos\XamFormsMaps\XamFormsMaps\XamFormsMaps.Core\Services\DatabaseService.cs:20,13 C#
0x7A in XamFormsMaps.Core.ViewModels.MapViewModel.GetPlacesAsync at C:\Users\Role\source\repos\XamFormsMaps\XamFormsMaps\XamFormsMaps.Core\ViewModels\MapViewModel.cs:112,17 C#
0x6D in XamFormsMaps.Core.Pages.MapPage.<-ctor<-ctor>b__0_1>d at C:\Users\Role\source\repos\XamFormsMaps\XamFormsMaps\XamFormsMaps.Core\Pages\MapPage.xaml.cs:27,17 C#
Solved.
First, I had to change the Location type in the model to:
GeoJsonPoint<GeoJson2DGeographicCoordinates> _location;
[BsonElement("Location")]
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Location
{
get => _location;
set
{
if (_location == value)
return;
_location = value;
HandlePropertyChanged();
}
}
Then, I used the following query:
var geoPoint = new GeoJsonPoint<GeoJson2DGeographicCoordinates>(new GeoJson2DGeographicCoordinates(22, -5));
var query = Builders<Place>.Filter.Near(p => p.Location, geoPoint, 30000);
var result = await PlacesCollection.Find(query).ToListAsync();
Do you happen to have the stack trace of the exception you had previous to your solution? I'd like to take a look to see what the problem was.
Trying to create kind of market scanner. Code below is supposed to return chain of option contracts. Call to TWS API is an async method that returns some data only if I get ContractEnd or Error response from TWS. On the first call to reqContractDetails() it works as expected, I get list of contracts, receive message "ContractEnd", and exit from the method.
Obstacle
In some reason, on the second call to reqContractDetails() I don't get any notification from TWS. I have to stop and restart my application, initiating new connection to the server to make it working again.
Update
After refactoring my code I'm getting an error on a second call that says "Unable to read beyond the end of the stream". Call stack looks this way.
IBLibrary.dll!IBLibrary.OptionService.GetOptionsChain.AnonymousMethod__3(IBLibrary.Messages.ErrorMessage data) Line 64
IBLibrary.dll!IBLibrary.Classes.Client.error(string str) Line 42
CSharpAPI.dll!IBApi.EReader.putMessageToQueue() Line 94
CSharpAPI.dll!IBApi.EReader.Start.AnonymousMethod__9_0() Line 48
My implementation of the wrapper in C#
public class BaseService : IDisposable
{
protected Client Sender { get; set; }
protected EReader Receiver { get; set; }
public BaseService()
{
Sender = new Client();
Sender.Socket.eConnect("127.0.0.1", 7496, 0);
Receiver = new EReader(Sender.Socket, Sender.Signal);
Receiver.Start();
var process = new Thread(() =>
{
while (Sender.Socket.IsConnected())
{
Sender.Signal.waitForSignal();
Receiver.processMsgs();
}
})
{
IsBackground = true
};
process.Start();
}
public void Dispose()
{
Sender.Socket.eDisconnect();
}
}
public class OptionService : BaseService
{
public Task<List<OptionModel>> GetOptionsChain(OptionModel query)
{
if (query == null)
{
query = new OptionModel();
}
var process = Task.Run(() =>
{
var done = false;
var id = new Random(DateTime.Now.Millisecond).Next();
var contract = new Contract
{
Symbol = query.Symbol,
SecType = "OPT",
Exchange = "SMART",
Currency = "USD",
LastTradeDateOrContractMonth = query.Expiration
};
var contracts = new List<OptionModel>();
Action<ErrorMessage> errorMessage = null;
Action<ContractDetailsMessage> contractMessage = null;
Action<ContractDetailsEndMessage> contractMessageEnd = null;
contractMessage = (ContractDetailsMessage data) =>
{
contracts.Add(new OptionModel
{
Symbol = data.ContractDetails.Contract.Symbol,
Right = data.ContractDetails.Contract.Right,
Strike = data.ContractDetails.Contract.Strike,
Expiration = data.ContractDetails.RealExpirationDate
});
};
// I receive this message at first, but not the second time
contractMessageEnd = (ContractDetailsEndMessage data) =>
{
done = true;
};
errorMessage = (ErrorMessage data) =>
{
var notifications = new List<int>
{
(int) ErrorCode.MarketDataFarmConnectionIsOK,
(int) ErrorCode.HmdsDataFarmConnectionIsOK
};
if (notifications.Contains(data.ErrorCode) == false)
{
done = true;
}
};
Sender.ErrorEvent += errorMessage;
Sender.ContractDetailsEvent += contractMessage;
Sender.ContractDetailsEndEvent += contractMessageEnd;
Sender.Socket.reqContractDetails(id, contract);
// Execute method until we get all contracts
// The econd call to reqContractDetails doesn't return
// any notification, so obviously this line hangs forever
while (done == false);
Sender.ErrorEvent -= errorMessage;
Sender.ContractDetailsEvent -= contractMessage;
Sender.ContractDetailsEndEvent -= contractMessageEnd;
return contracts;
});
return process;
}
}
As far as nobody has the answer, even IB itself, the only solution that I see is, to convert my API controller to a synchronous controller and close socket connection to IB server after every request.
Old version.
public class ServiceOptionsController : BaseServiceController
{
OptionService Service = new OptionService();
[AcceptVerbs("POST")]
public async Task<List<OptionModel>> Options([FromBody] dynamic data)
{
var selectors = data.ToObject<QueryModel>();
var optionModel = new OptionModel
{
Symbol = "MSFT",
Expiration = "201806"
};
var processes = new List<Task<List<OptionModel>>>
{
Service.GetOptionsChain(optionModel)
};
return (await Task.WhenAll(processes)).SelectMany(o => o).ToList();
}
}
Working version.
public class ServiceOptionsController : BaseServiceController
{
[AcceptVerbs("POST")]
public List<OptionModel> Options([FromBody] dynamic data)
{
var selectors = data.ToObject<QueryModel>();
var optionModel = new OptionModel
{
Symbol = "MSFT",
Expiration = "201806"
};
var optionService = new OptionService();
var processes = new List<Task<List<OptionModel>>>
{
optionService.GetOptionsChain(optionModel)
};
var items = Task.WhenAll(processes).Result.SelectMany(o => o).ToList();
optionService.Dispose(); // Ridiculous fix for ridiculous API
return items;
}
}
I'm writting a control software / HMI using this ua-client for WPF, with Kepwere as OPC Server.
Today I was doing some connection tests, disconnecting the ethernet cable of my PLC and change some monitored item value in the software. Obviously this change wont take effect because the connection state, but, after reconnect why don't refresh the PLC tag with the value that I previously set?
Or this is the expected behavior and I need to make some internal storage variable to replicate this?
Kepserver have a System.NoError Tag that indicate if there is an error on the PLC, so I know when the PLC is offline. But I'm trying to resend the latest change while was offline whe it reconnect.
I overwrote the SetProperty method:
protected override bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if(ServerState != CommunicationState.Opened || (!System_NoError && "System_NoError" != propertyName))
{
m_eventsPending.Add(new WriteEvent
{
PropertyName = propertyName,
PropertyValue = value
});
return false;
}
return base.SetProperty(ref storage, value, propertyName);
}
And then listen to the server state change event with this:
public void OnStateChangeEvent(CommunicationState state)
{
ServerState = state;
}
On every change on System_NoError I do:
private void OnError()
{
if(System_NoError)
{
while(m_eventsPending.Count > 0)
{
WriteEvent e = m_eventsPending.ElementAt(0);
bool storage = !(bool)e.PropertyValue;
var p = this.GetType().GetProperty(e.PropertyName);
p.SetValue(this, storage);
p.SetValue(this, e.PropertyValue);
m_eventsPending.RemoveAt(0);
}
}
}
I do some initialization and keep it on the m_eventsPending list, and start sending when connection is complete (Opened), but nothing happend on the PLC side. What could be wrong?
P.S: Any other interaction with the software make the correct change on the PLC, acording to my code (buttons, slider, etc)
Best Regards
Jose Truyol
Consider writing the tag directly in the property setter. This example tries writing the Green light, retrying every 5 seconds until successful.
public class TrafficLightViewModel : ViewModelBase
{
private bool green;
private bool red;
private bool yellow;
private CancellationTokenSource greenCts;
private CancellationTokenSource redCts;
private CancellationTokenSource yellowCts;
private UaTcpSessionClient session;
public TrafficLightViewModel(UaTcpSessionClient session)
{
this.session = session;
}
public bool Green
{
get { return this.green; }
set
{
this.green = value;
this.greenCts?.Cancel();
this.greenCts = new CancellationTokenSource();
var request = new WriteRequest
{
NodesToWrite = new[]
{
new WriteValue
{
NodeId = NodeId.Parse("ns=2;s=GreenLight"),
AttributeId = AttributeIds.Value,
Value = new DataValue(value)
}
}
};
this.WriteOutputAsync(request, this.greenCts.Token);
}
}
// add yellow and red
private async void WriteOutputAsync(WriteRequest request, CancellationToken token)
{
try
{
while (!await this.TryWriteAsync(request))
{
await Task.Delay(5000, token);
}
}
catch (TaskCanceledException)
{
Debug.WriteLine($"Canceled writing output : {request.NodesToWrite[0].NodeId}");
}
}
private async Task<bool> TryWriteAsync(WriteRequest request)
{
try
{
var response = await this.session.WriteAsync(request);
for (int i = 0; i < response.Results.Length; i++)
{
if (StatusCode.IsBad(response.Results[i]))
{
Debug.WriteLine($"Error writing output '{request.NodesToWrite[i].NodeId}' {request.NodesToWrite[i].Value.GetValue()}: {StatusCodes.GetDefaultMessage(response.Results[i])}");
return false;
}
}
return true;
}
catch (Exception ex)
{
Debug.WriteLine($"Error writing outputs : {ex.Message}");
return false;
}
}
}
Hope this helps.
Andrew
I connect to several APIs that all use FXI4.2 but now I wish to connect to another that uses its own version of FIX4.4.
I have an router app that send orders to the various APIs and it would appear that I need to duplicate all my methods (e.g. the OnMessage(), NewSingleOrder etc) to cope with the 2 FIX protocols.
Is there a smarter way to do this to avoid this duplication?
Moderators: I know this is a little open now, but I will add some code snippets once I get some initial feedback.
public void OnMessage(QuickFix.FIX42.MarketDataIncrementalRefresh message, SessionID sessionID)
{
int count = message.NoMDEntries.getValue();
QuickFix.FIX42.MarketDataSnapshotFullRefresh.NoMDEntriesGroup repeatingMDItem = new QuickFix.FIX42.MarketDataSnapshotFullRefresh.NoMDEntriesGroup();
DateTime sourceDT = DateTime.ParseExact(message.Header.GetField(52), "yyyyMMdd-HH:mm:ss.fff", ci);
DateTime dt = TimeZoneInfo.ConvertTimeToUtc(sourceDT, utcZone);
DateTime nowUTC = TimeZoneInfo.ConvertTime(DateTime.UtcNow, utcZone, utcZone);
TimeSpan diffToUK = nowUTC - dt;
for (int i = 1; i <= count; i++)
{
message.GetGroup(i, repeatingMDItem);
String symbol = repeatingMDItem.GetField(55);
int tickBandNoDecPlaces = int.Parse(repeatingMDItem.GetField(5071));
masterForm.MDATA.AddData(symbol, tickBandNoDecPlaces, sourceDT);
}
}
Question: Will FIX44 accept all previous FIX?
How can I make this agnostic about which FIX version?
public void OnMessage(QuickFix.FIX42.MarketDataSnapshotFullRefresh message, SessionID sessionID)
{
OnMessageAgnostic(message, sessionID);
}
public void OnMessage(QuickFix.FIX44.MarketDataSnapshotFullRefresh message, SessionID sessionID)
{
OnMessageAgnostic(message, sessionID);
}
public int FixVersion(QuickFix.Message message)
{
switch (message.GetString(8)) // BeginString
{
case Values.BeginString_FIX42:
return 42;
case Values.BeginString_FIX44:
return 44;
default:
throw new NotSupportedException("This version of FIX is unsupported");
}
}
public void OnMessageAgnostic(QuickFix.Message message, SessionID sessionID)
{
int count;
if (FixVersion(message)==44)
{
count = ((QuickFix.FIX44.MarketDataSnapshotFullRefresh)message).NoMDEntries.getValue();
}
}
The problem is that is that FIX message types from different versions don't have any relationship except for their base class - at the lowest level, all FIX messages derive from Message. You need to take the information you need from a message, package it in such a way that it's version-agnostic (as far as is possible), and then write code against those version-agnostic data structures.
I suggest that you let the message cracker do the initial filtering for you, if you're OK to let it handle that, and then feed the message to a handler that can deal with that particular type of message:
public void OnMessage(QuickFix.FIX42.MarketDataIncrementalRefresh message, SessionID sessionID)
{
this.marketDataIncrementalRefreshHandler.Handle(message);
}
public void OnMessage(QuickFix.FIX44.MarketDataIncrementalRefresh message, SessionID sessionID)
{
this.marketDataIncrementalRefreshHandler.Handle(message);
}
... elsewhere ...
public interface FixMessageHandler
{
void Handle(Message msg);
}
public class MarketDataIncrementalRefreshHandler : FixMessageHandler
{
public void Handle(Message msg)
{
DateTime sourceDT = DateTime.ParseExact(message.Header.GetField(52), "yyyyMMdd-HH:mm:ss.fff", ci);
DateTime dt = TimeZoneInfo.ConvertTimeToUtc(sourceDT, utcZone);
DateTime nowUTC = TimeZoneInfo.ConvertTime(DateTime.UtcNow, utcZone, utcZone);
TimeSpan diffToUK = nowUTC - dt;
var noMDEntriesGroups = this.GetAllNoMDEntries(msg)
foreach (var noMDEntriesGroup in noMDEntriesGroups)
{
masterForm.MDATA.AddData(
noMDEntriesGroup.Symbol,
noMDEntriesGroup.TickBandNoDecPlaces,
sourceDT);
}
}
private IEnumerable<NoMDEntriesGroup> GetAllNoMDEntries(Message msg)
{
switch (message.GetString(8)) // BeginString
{
case Values.BeginString_FIX42:
return this.GetAllNoMDEntries((QuickFix.FIX42.MarketDataSnapshotFullRefresh)msg);
case Values.BeginString_FIX44:
return this.GetAllNoMDEntries((QuickFix.FIX44.MarketDataSnapshotFullRefresh)msg);
default:
throw new NotSupportedException("This version of FIX is unsupported");
}
}
private IEnumerable<NoMDEntriesGroup> GetAllNoMDEntries(QuickFix.FIX42.MarketDataSnapshotFullRefresh msg)
{
int count = message.NoMDEntries.getValue();
QuickFix.FIX42.MarketDataSnapshotFullRefresh.NoMDEntriesGroup repeatingMDItem = new QuickFix.FIX42.MarketDataSnapshotFullRefresh.NoMDEntriesGroup();
for (int i = 1; i <= count; i++)
{
message.GetGroup(i, repeatingMDItem);
yield return new NoMDEntriesGroup
{
Symbol = repeatingMDItem.GetField(55),
TickBandNoDecPlaces = int.Parse(repeatingMDItem.GetField(5071)
};
}
}
private IEnumerable<NoMDEntriesGroup> GetAllNoMDEntries(QuickFix.FIX44.MarketDataSnapshotFullRefresh msg)
{
// Should be practically identical to the above version, with 4.4 subbed for 4.2
}
private class NoMDEntriesGroup
{
public string Symbol { get; set; }
public int TickBandNoDecPlaces { get; set; }
}
}
I want to calculate the total data download and upload in a particular interval of time, and store it to a database so that it can be viewed later on. Thus, this particular user logged in at this time and downloaded and uploaded this much data.
I want to do this in C#.
You can do it using PerformanceCounter class in System.Diagnostics namespace.
Noting down two class that will help you achive what you want to do.
NetworkMonitor class
public class NetworkMonitor
{
private ArrayList adapters;
public ArrayList monitoredAdapters;
public NetworkMonitor()
{
this.adapters = new ArrayList();
this.monitoredAdapters = new ArrayList();
EnumerateNetworkAdapters();
}
private void EnumerateNetworkAdapters()
{
PerformanceCounterCategory category = new PerformanceCounterCategory("Network Interface");
foreach (string name in category.GetInstanceNames())
{
if (name == "MS TCP Loopback interface")
continue;
NetworkAdapter adapter = new NetworkAdapter(name);
adapter.dlCounter = new PerformanceCounter("Network Interface", "Bytes Received/sec", name);
adapter.ulCounter = new PerformanceCounter("Network Interface", "Bytes Sent/sec", name);
this.adapters.Add(adapter);
adapter.init();
}
}
public NetworkAdapter[] Adapters
{
get
{
return (NetworkAdapter[])this.adapters.ToArray(typeof(NetworkAdapter));
}
}
}
NetworkAdapter class
public class NetworkAdapter
{
// Instances of this class are supposed to be created only in an NetworkMonitor.
internal NetworkAdapter(string name)
{
this.name = name;
}
private long dlSpeed, ulSpeed;
private long dlValue, ulValue;
private long dlValueOld, ulValueOld;
internal string name;
internal PerformanceCounter dlCounter, ulCounter;
internal bool Enabled;
internal void init()
{
this.dlValueOld = this.dlCounter.NextSample().RawValue;
this.ulValueOld = this.ulCounter.NextSample().RawValue;
this.Enabled = true;
}
// Obtain new sample from performance counters, and refresh the values saved in dlSpeed, ulSpeed, etc.
// This method is supposed to be called only in NetworkMonitor, one time every second.
internal void refresh()
{
this.dlValue = this.dlCounter.NextSample().RawValue;
this.ulValue = this.ulCounter.NextSample().RawValue;
// Calculates download and upload speed.
this.dlSpeed = this.dlValue - this.dlValueOld;
this.ulSpeed = this.ulValue - this.ulValueOld;
this.dlValueOld = this.dlValue;
this.ulValueOld = this.ulValue;
}
// Overrides method to return the name of the adapter.
public override string ToString()
{
return this.name;
}
public string Name
{
get
{
return this.name;
}
}
// Current download speed in bytes per second.
public long DownloadSpeed(int Interval)
{
return this.dlSpeed * 1000 / Interval;
}
// Current upload speed in bytes per second.
public long UploadSpeed(int Interval)
{
return this.ulSpeed * 1000 / Interval;
}
}
All you have to do is:
long downloadSpeed = 0;
long uploadSpeed = 0;
NetworkMonitor networkMonitor = new NetworkMonitor();
foreach (NetworkAdapter adapter in monitor.Adapters)
{
if (adapter.Enabled)
{
adapter.refresh();
downloadSpeed += adapter.DownloadSpeed(yourTimerInterval);
uploadSpeed += adapter.UploadSpeed(yourTimerInterval);
}
}
Hope this helps.
Regards.