WebRequests in C# are very CPU Intensive. Need something better - c#

I have a program that needs to scan for other devices running my program on the network. The solution I came up with was to call each ipAddress to see if my program is running.
The code below is completely blocking the cpu:-
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FileWire
{
class SearchNearby
{
private bool pc_search_cancelled = false;
private SynchronizedCollection<Thread> PCSearchThreadList;
private ConcurrentDictionary<String, String> NearbyPCList;
public void NewPcFound(string s, string s1)
{
Console.WriteLine(string.Format("PC Found at: {0} PC Name: {1}", s, s1));
}
public SearchNearby()
{
startPCScan();
while (true)
{
bool isAnyAlive = false;
foreach(Thread t in PCSearchThreadList)
{
isAnyAlive |= t.IsAlive;
}
if (!isAnyAlive)
{
Console.WriteLine("Search Complete");
foreach (var a in NearbyPCList)
{
Console.WriteLine(a.Key + " ;; " + a.Value);
}
startPCScan();
}
Thread.Sleep(100);
}
}
private void startPCScan()
{
PCSearchThreadList = new SynchronizedCollection<Thread>();
NearbyPCList = new ConcurrentDictionary<String, String>();
pc_search_cancelled = false;
String add = "";
System.Net.IPAddress[] ad = System.Net.Dns.GetHostByName(System.Net.Dns.GetHostName()).AddressList;
foreach (System.Net.IPAddress ip in ad)
{
add += ip.ToString() + "\n";
}
bool connected;
if (add.Trim(' ').Length == 0)
{
connected = false;
}
else
{
connected = true;
}
if (connected)
{
try
{
String[] addresses = add.Split('\n');
foreach (String address in addresses)
{
int myIP = int.Parse(address.Substring(address.LastIndexOf(".") + 1));
for (int def = 0; def <= 10; def++)
{
int finalDef = def;
for (int j = 0; j < 10; j++)
{
string finalJ = j.ToString();
Thread thread = new Thread(new ThreadStart(() =>
{
if (!pc_search_cancelled)
{
for (int i = (finalDef * 25); i < (finalDef * 25) + 25 && i <= 255; i++)
{
if (!pc_search_cancelled)
{
if (i != myIP)
{
String callToAddress = "http://" + address.Substring(0, address.LastIndexOf(".")) + "." + i + ":" + (1234 + int.Parse(finalJ)).ToString();
String name = canGetNameAndAvatar(callToAddress);
if (name != null)
{
NearbyPCList[callToAddress] = name;
NewPcFound(callToAddress, name);
}
}
}
}
}
}));
PCSearchThreadList.Add(thread);
thread.Start();
}
}
}
} catch (Exception e) {
}
}
}
private String canGetNameAndAvatar(String connection)
{
String link = connection + "/getAvatarAndName";
link = link.Replace(" ", "%20");
try
{
var client = new HttpClient();
client.Timeout = TimeSpan.FromMilliseconds(500);
var a = new Task<HttpResponseMessage>[1];
a[0] = client.GetAsync(link);
Task.WaitAll(a);
var b = a[0].Result.Content.ReadAsStringAsync();
Task.WaitAll(b);
Console.WriteLine(b.Result);
string result = b.Result;
result = result.Substring(result.IndexOf("<body>") + 6, result.IndexOf("</body>") - (result.IndexOf("<body>") + 6));
AvtarAndName json = JsonConvert.DeserializeObject<AvtarAndName>(result);
if (json != null)
{
return json.name;
}
}
catch
{
return null;
}
return null;
}
}
}
This is the exact C# version of the java code I was using in Java:-
import com.sun.istack.internal.Nullable;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class PCScan {
private static boolean pc_search_cancelled = false;
private static List<Thread> PCSearchThreadList;
private static HashMapWithListener<String, String> NearbyPCList;
public static void main(String[] args) {
start();
while (true) {
int numCompleted = 0;
for (Thread t : PCSearchThreadList) {
if (!t.isAlive()) {
numCompleted++;
}
}
if (numCompleted == PCSearchThreadList.size()) {
start();
}
}
}
private static void start() {
try {
startPCScan();
} catch (SocketException e) {
e.printStackTrace();
}
NearbyPCList.setPutListener(new HashMapWithListener.putListener() {
#Override
public void onPut(Object key, Object value) {
System.out.println(key.toString() + ";;" + value.toString());
}
});
}
private static void startPCScan() throws SocketException {
pc_search_cancelled = false;
PCSearchThreadList = new CopyOnWriteArrayList<>();
NearbyPCList = new HashMapWithListener<>();
Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
boolean connected;
String add = "";
while (enumeration.hasMoreElements()) {
NetworkInterface interfacea = enumeration.nextElement();
if (!interfacea.isLoopback()) {
Enumeration<InetAddress> enumeration1 = interfacea.getInetAddresses();
while (enumeration1.hasMoreElements()) {
String address = enumeration1.nextElement().getHostAddress();
if (address.split("\\.").length == 4) {
add += address + "\n";
}
}
}
}
System.out.println(add);
connected = true;
if (connected) {
try {
String[] addresses = add.split("\n");
addresses = new HashSet<String>(Arrays.asList(addresses)).toArray(new String[0]);
for (String address : addresses) {
int myIP = Integer.parseInt(address.substring(address.lastIndexOf(".") + 1));
for (int def = 0; def <= 10; def++) {
int finalDef = def;
for (int j = 0; j < 10; j++) {
int finalJ = j;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
if (!pc_search_cancelled) {
for (int i = (finalDef * 25); i < (finalDef * 25) + 25 && i <= 255; i++) {
if (!pc_search_cancelled) {
if (i != myIP) {
String callToAddress = "http://" + address.substring(0, address.lastIndexOf(".")) + "." + i + ":" + String.valueOf(Integer.parseInt("1234") + finalJ);
String name = canGetNameAndAvatar(callToAddress);
if (name != null) {
NearbyPCList.put(callToAddress, name);
}
}
}
}
}
}
});
PCSearchThreadList.add(thread);
thread.start();
}
}
// }
// }).start();
}
} catch (Exception e) {
}
}
}
private static String canGetNameAndAvatar(String connection) {
String link = connection + "/getAvatarAndName";
link = link.replaceAll(" ", "%20");
try {
HttpClient client = new DefaultHttpClient();
HttpParams httpParams = client.getParams();
httpParams.setParameter(
CoreConnectionPNames.CONNECTION_TIMEOUT, 500);
HttpGet request = new HttpGet();
request.setURI(new URI(link));
HttpResponse response = client.execute(request);
BufferedReader in = new BufferedReader(new
InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line="";
while ((line = in.readLine()) != null) {
sb.append(line);
break;
}
in.close();
String result = sb.toString();
result = result.substring(result.indexOf("<body>") + 6, result.indexOf("</body>"));
JSONObject json = new JSONObject(result);
if (json != null) {
return json.getString("name");
}
}
catch (Exception ignored){
return null;
}
return null;
}
static class HashMapWithListener<K, V> extends HashMap<K, V> {
private putListener PutListener;
public void setPutListener(putListener PutListener) {
this.PutListener = PutListener;
}
#Nullable
#Override
public V put(K key, V value) {
PutListener.onPut(key, value);
return super.put(key, value);
}
interface putListener {
public void onPut(Object key, Object value);
}
}
}
The java code runs absolutely fine and only uses about 20 percent cpu while c# code absolutely locks the PC. I tried Webclient, webrequest, httpClient. All have literally the same performance.
I need the code to be in c# as I can't include whole JRE in my program since it is too large. The rest of my program and GUI is in WPF format.
Also, I need the code to take a maximum of 50seconds while scanning ports 1234-1243. This code also works absolutely fine even on a midrange android phone. So, I don't know what the problem is.

I would suggest something like this (I've simplified it for the sake of an example):
private static HttpClient _client = new HttpClient() { Timeout = TimeSpan.FromMilliseconds(500) };
private async Task<Something> GetSomething(string url)
{
using (HttpResponseMessage response = await _client.GetAsync(url))
{
string json = await response.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Something>(json);
}
}
private async Task<Something[]> GetSomethings(string[] urls)
{
IEnumerable<Task<Something>> requestTasks = urls.Select(u => GetSomething(u));
Something[] results = await Task.WhenAll<Something>(requestTasks);
return results;
}
You should also make the method calling GetSomethings async, and await it, and do the same all the way up the call chain.
async/await uses a thread pool to execute, and the thread is actually suspended while the IO part of the request occurs, meaning that no CPU time is used during this period. When then IO part is done, it resumes the code at the await.
Related information:
Asynchronous programming documentation
How and when to use 'async' and 'await'

You are using threads and multithreading completely wrong.
Because I cannot really understand what you are trying to do because everything is cramped into one function, I cannot provide you with a more detailed solution.
But let me suggest the following: I understand, you want to execute some operation in the background connecting to some other computer, try something like this
var taskList = new List<Task>();
foreach (var pc in computers)
{
var currentPcTask = Task.Run(() => DoYourWorkForSomePcHere(pc));
taskList.Add(currentPcTask);
}
Task.WaitAll(taskList.ToArray());
This will be very CPU efficient.

Related

Multithreaded Selenium Bot does not work correctly

I wrote a bot in C#, I used Selenium.
Problem: When I start more threads at same time, the bot does the work in the first window. All of the e-mail addresses are being added to the "E-mail" textbox in the same window instead of one e-mail address per window.
But it should look like:
Start function: DivisionStart()
private void DivisionStart() {
foreach(var account in BotConfig.AccountList) {
while (CurrentBotThreads >= BotConfig.MaxLoginsAtSameTime) {
Thread.Sleep(1000);
}
StartedBotThreads++;
CurrentBotThreads++;
int startIndex = (StartedBotThreads * BotConfig.AdsPerAccount + 1) - BotConfig.AdsPerAccount - 1;
int stopIndex = BotConfig.AdsPerAccount * CurrentBotThreads;
if (stopIndex > BotConfig.ProductList.Count) {
stopIndex = BotConfig.ProductList.Count;
}
Debug.Print("Thread: " + StartedBotThreads);
var adList = GetAdListBy(startIndex, stopIndex);
foreach(var ad in adList) {
Debug.Print("Für thread: " + StartedBotThreads + " | Anzeige: " + ad.AdTitle);
}
Debug.Print("Parallel");
var ebayBotThread = new Thread(() => {
var botOptions = new IBotOptionsModel() {
CaptchaSolverApiKey = CaptchaSolverApiKey,
ReCaptchaSiteKey = "6LcZlE0UAAAAAFQKM6e6WA2XynMyr6WFd5z1l1Nr",
StartPageUrl = "https://www.ebay-kleinanzeigen.de/m-einloggen.html?targetUrl=/",
EbayLoginEmail = account.AccountEmail,
EbayLoginPassword = account.AccountPassword,
Ads = adList,
};
var ebayBot = new EbayBot(this, botOptions);
ebayBot.Start(StartedBotThreads);
Thread.Sleep(5000);
});
ebayBotThread.Start();
}
}
The class with function which will be executed in each thread:
using OpenQA.Selenium;
using Selenium.WebDriver.UndetectedChromeDriver;
using System.Diagnostics;
using TwoCaptcha.Captcha;
using System.Drawing;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chrome.ChromeDriverExtensions;
namespace EbayBot
{
class EbayBot
{
public Selenium.Extensions.SlDriver Driver;
private WebDriverHelper DriverHelper;
private Bot Sender;
private bool CaptchaSolved = false;
public IBotOptionsModel Options;
public EbayBot(Bot sender, IBotOptionsModel options)
{
Sender = sender;
Options = options;
}
public void Start(int threadIndex)
{
var chromeOptions = new ChromeOptions();
/*if (Sender.BotConfig.EnableProxy)
{
chromeOptions.AddHttpProxy(
Options.Proxy.IpAddress,
Options.Proxy.Port,
Options.Proxy.Username,
Options.Proxy.Password
);
}*/
Driver = UndetectedChromeDriver.Instance(null, chromeOptions);
DriverHelper = new WebDriverHelper(Driver);
string status = "";
Debug.Print("Bot-Thread: " + threadIndex);
Driver.Url = Options.StartPageUrl + Options.EbayLoginEmail;
PressAcceptCookiesButton();
Login();
if (!CaptchaSolved) return;
Driver.Wait(3);
if (LoginError() || !IsLoggedIn())
{
status = "Login für '" + Options.EbayLoginEmail + "' fehlgeschlagen!";
Debug.Print(status);
Sender.ProcessStatus = new IStatusModel(status, Color.Red);
return;
}
else
{
status = "Login für '" + Options.EbayLoginEmail + "' war erfolgreich!";
Debug.Print(status);
Sender.ProcessStatus = new IStatusModel(status, Color.Green);
}
Driver.Wait(5);
BeginFillFormular();
}
private bool CookiesAccepted()
{
try
{
var btnAcceptCookies = Driver.FindElement(By.Id(Config.PageElements["id_banner"]));
return btnAcceptCookies == null;
}
catch (Exception)
{
return true;
}
}
private void PressAcceptCookiesButton()
{
DriverHelper.WaitForElement(Config.PageElements["id_banner"], "", 10);
if (CookiesAccepted()) return;
var btnAcceptCookies = Driver.FindElement(By.Id(Config.PageElements["id_banner"]));
btnAcceptCookies.Click();
}
private bool IsLoggedIn()
{
Debug.Print("Check if logged in already");
try
{
var userEmail = Driver.FindElement(By.Id("user-email")).Text;
return userEmail.ToLower().Contains(Options.EbayLoginEmail);
}
catch (Exception)
{
return false;
}
}
private bool LoginError()
{
try
{
var loginErrorH1 = Driver.FindElements(By.TagName("h1"));
return loginErrorH1[0].Text.Contains("ungültig");
}
catch (Exception)
{
return false;
}
}
private void Login()
{
if (IsLoggedIn()) return;
string status = "Anmelden bei " + Options.EbayLoginEmail + "...";
Debug.Print(status);
Sender.ProcessStatus = Sender.ProcessStatus = new IStatusModel(status, Color.DimGray);
Driver.Wait(5);
var fieldEmail = Driver.FindElement(By.Id(Config.PageElements["id_login_email"]));
var fieldPassword = Driver.FindElement(By.Id(Config.PageElements["id_login_password"]));
var btnLoginSubmit = Driver.FindElement(By.Id(Config.PageElements["id_login_button"]));
fieldEmail.SendKeys(Options.EbayLoginEmail);
Driver.Wait(4);
fieldPassword.SendKeys(Options.EbayLoginPassword);
SolveCaptcha();
if (!CaptchaSolved)
{
return;
}
Debug.Print("Clicking login button");
btnLoginSubmit.Click();
}
public void BeginFillFormular()
{
Debug.Print("Formular setup, Inserate: " + Options.Ads.Count);
foreach (var adData in Options.Ads)
{
Debug.Print("Setting up formular for " + adData.AdTitle);
var adFormular = new AdFormular(Driver, adData, Options);
adFormular._EbayBot = this;
adFormular.CreateAd(Sender);
// 10 seconds
Debug.Print("Nächstes Insert für " + adData.AdTitle);
}
}
public string GetSolvedCaptchaAnswer(string captchaUrl = "")
{
string code = string.Empty;
var solver = new TwoCaptcha.TwoCaptcha(Options.CaptchaSolverApiKey);
var captcha = new ReCaptcha();
captcha.SetSiteKey(Options.ReCaptchaSiteKey);
captcha.SetUrl(captchaUrl == "" ? Options.StartPageUrl : captchaUrl);
try
{
solver.Solve(captcha).Wait();
code = captcha.Code;
}
catch (AggregateException e)
{
Sender.ProcessStatus = new IStatusModel("Captcha Api-Fehler: " + e.InnerExceptions.First().Message, Color.Red);
Driver.Wait(10);
}
return code;
}
public void SolveCaptcha(string captchaUrl = "")
{
Debug.Print("Solving captcha...");
var solvedCaptchaAnswer = GetSolvedCaptchaAnswer(captchaUrl);
if (solvedCaptchaAnswer == string.Empty)
{
Debug.Print("Captcha konnte nicht gelöst werden");
Sender.ProcessStatus = new IStatusModel("Captcha konnte nicht gelöst werden", Color.Red);
CaptchaSolved = false;
Driver.Wait(10);
return;
}
CaptchaSolved = true;
Debug.Print("Captcha answer: " + solvedCaptchaAnswer);
Driver.ExecuteScript("document.getElementById('g-recaptcha-response').innerHTML = '" + solvedCaptchaAnswer + "'");
Debug.Print("Captcha solved!");
Driver.Wait(2);
}
}
}
If I remove the Thread.Sleep(5000); in the DivisionStart function it will work, but I need it I actually want to wait for a found proxy but I simulated it with Thread.Sleep
How can I solve my problem?
Thanks for any answer!
I fixed it.
I used UndetectedChromeDriver wich does not use different ports.
I use another Undetected driver now.
Thank you all

C# ClientWebSocket not receiving all packets?

I've built a windows service that subscribes to around 10,000 stock tickers in real-time using ClientWebSocket. If I subscribe to 1,000 tickers I receive all the data points as I should (receiving few hundred messages a second), as soon as I get up to 2,000 tickers I don't seem to be receiving the data I should be, 10,000 (receiving thousands of messages a second) its even worse. I've run comparison reports and it looks like I'm losing up to 60% of the packets. I've talked to polygon (the provider of the real-time data) about this issue and they claim their Socket is a firehose and everything that should go out, goes out, and that none of their other clients are complaining. So the only logical thing here would to be to assume its my code, or some limitation. Maybe it's the Task portion of the Receive method? Maybe window's has a max task limitation and I'm exceeding it.
I've also tested this on a high powered dedicated server with 10gb connection so it doesnt seem to be a connection or hardware limitation.
I've also by passed my BlockingCollection cache and the problem still persisted.
Hopefully one of you has some insight, thank you!
Here's my code:
public static ConcurrentDictionary<string, TradeObj> TradeFeed = new ConcurrentDictionary<string, TradeObj>();
public static ConcurrentDictionary<string, QuoteObj> QuoteFeed = new ConcurrentDictionary<string, QuoteObj>();
public static ConcurrentDictionary<string, AggObj> AggFeed = new ConcurrentDictionary<string, AggObj>();
public static BlockingCollection<byte[]> packets = new BlockingCollection<byte[]>();
private static void Start(string[] args)
{
try
{
Polygon.StartSub();
int HowManyConsumers = 2;
for (int i = 0; i < HowManyConsumers; i++)
{
Task.Factory.StartNew(Polygon.ConsumePackets);
}
} catch(Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
public static async Task StartSub()
{
do
{
using (var socket = new ClientWebSocket())
try
{
// socket.Options.KeepAliveInterval = TimeSpan.Zero;
var Connection = "wss://socket.polygon.io/stocks";
await socket.ConnectAsync(new Uri(Connection), CancellationToken.None);
Console.WriteLine("Websocket opened to Polygon.");
await Send(socket, "{\"action\":\"auth\",\"params\":\""+ConfigurationManager.AppSettings["PolygonAPIToken"]+"\"}");
List<List<string>> batches = new List<List<string>>();
for (int i = 0; i < FeedCache.Tickers.Count(); i += 500)
{
var tempList = new List<string>();
tempList.AddRange(FeedCache.Tickers.Skip(i).Take(500));
batches.Add(tempList);
}
int bNum = 0;
string[] quoteStrings = new string[batches.Count()];
foreach (var tList in batches)
{
var tQuery = "";
tQuery = tQuery + "T." + string.Join(",T.", tList.ToArray());
tQuery = tQuery + ",A." + string.Join(",A.", tList.ToArray());
tQuery = tQuery + ",Q." + string.Join(",Q.", tList.ToArray());
quoteStrings[bNum] = tQuery;
bNum++;
}
for (int i = 0; i < quoteStrings.Count(); i++)
{
string SubscribeString = "{\"action\":\"subscribe\",\"params\":\"" + quoteStrings[i] + "\"}";
await Send(socket, SubscribeString);
}
await Receive(socket);
}
catch (Exception ex)
{
Console.WriteLine($"ERROR - {ex.Message}");
Console.WriteLine(ex.ToString());
}
} while (true);
}
static async Task Send(ClientWebSocket socket, string data)
{
var segment = new ArraySegment<byte>(Encoding.UTF8.GetBytes(data));
await socket.SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None);
}
static async Task Receive(ClientWebSocket socket)
{
do {
WebSocketReceiveResult result;
var buffer = new ArraySegment<byte>(new byte[2000]);
using (var ms = new MemoryStream())
{
do
{
result = await socket.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.Array, buffer.Offset, result.Count);
} while (!result.EndOfMessage);
if (result.MessageType == WebSocketMessageType.Close)
{
await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Closed in server by the client", CancellationToken.None);
Console.WriteLine("Socket disconnecting, trying to reconnect.");
await StartSub();
}
else
{
packets.Add(ms.ToArray());
}
}
} while (true);
}
public static async void ConsumePackets()
{
foreach (var buffer in packets.GetConsumingEnumerable())
{
using (var ms = new MemoryStream(buffer))
{
ms.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
var data = await reader.ReadToEndAsync();
try
{
var j = JArray.Parse(data);
if (j != null)
{
string id = (string)j[0]["ev"];
switch (id)
{
case "T":
AddOrUpdateTrade((string)j[0]["sym"], j);
break;
case "Q":
AddOrUpdateQuote((string)j[0]["sym"], j);
break;
case "A":
AddOrUpdateAgg((string)j[0]["sym"], j);
break;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
}
public static void AddOrUpdateTrade(string ticker, JArray data)
{
TradeFeed.AddOrUpdate(ticker, new TradeObj {
LastPrice = (double)data[0]["p"],
TradeCount = 1
}, (key, existingVal) =>
{
return new TradeObj {
LastPrice = (double)data[0]["p"],
TradeCount = existingVal.TradeCount + 1,
PriceDirection = (double)data[0]["p"] < existingVal.LastPrice ? "D" : "U"
};
});
}
public static void AddOrUpdateAgg(string ticker, JArray data)
{
AggFeed.AddOrUpdate(ticker, new AggObj
{
TickVolume = (long)data[0]["v"],
VolumeShare = (long)data[0]["av"],
OpenPrice = (double)data[0]["op"],
TickAverage = (double)data[0]["a"],
VWAP = (double)data[0]["vw"],
TickClosePrice = (double)data[0]["c"],
TickHighPrice = (double)data[0]["h"],
TickLowPrice = (double)data[0]["l"],
TickOpenPrice = (double)data[0]["o"]
}, (key, existingVal) =>
{
return new AggObj
{
TickVolume = (long)data[0]["v"],
VolumeShare = (long)data[0]["av"],
OpenPrice = (double)data[0]["op"],
TickAverage = (double)data[0]["a"],
VWAP = (double)data[0]["vw"],
TickClosePrice = (double)data[0]["c"],
TickHighPrice = (double)data[0]["h"],
TickLowPrice = (double)data[0]["l"],
TickOpenPrice = (double)data[0]["o"]
};
});
}
public static void AddOrUpdateQuote(string ticker, JArray data)
{
QuoteFeed.AddOrUpdate(ticker, new QuoteObj
{
BidPrice = (double)data[0]["bp"],
BidSize = (double)data[0]["bs"],
AskPrice = (double)data[0]["ap"],
AskSize = (double)data[0]["as"]
}, (key, existingVal) =>
{
return new QuoteObj
{
BidPrice = (double)data[0]["bp"],
BidSize = (double)data[0]["bs"],
AskPrice = (double)data[0]["ap"],
AskSize = (double)data[0]["as"]
};
});
}

C# - connecting to SQL Server

At the beginning of my journey with C#, I am developing this simple Flashcard app. It can be used for learning vocabulary in new language.
I have created Flashcard class, also have been able to create functions allowing users to enter new words, revise them and play simple guessing game.
When creating new words, program ask user how many one, would like to create. Then uses object of Flashcard function n times, filling list with them.
After every operation like this, I'd like to insert new words, and its translation into a SQL Server database, although I've encountered first problem.
Flashcard.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlashCardApp
{
class Flashcard
{
private string Word;
private string Translation;
private string Description;
public bool IsKnownTemporarly;
public Flashcard(string word, string translation, string description)
{
Description = description;
Word = word;
Translation = translation;
IsKnownTemporarly = false;
}
public Flashcard()
{
Description = "Default description";
Translation = "Defualt translation";
Word = "Default word";
IsKnownTemporarly = false;
}
public Flashcard(Flashcard flashcard)
{
Description = flashcard.Description;
Word = flashcard.Word;
Translation = flashcard.Translation;
IsKnownTemporarly = flashcard.IsKnownTemporarly;
}
public string returnWord()
{
return Word;
}
public string returnDescription()
{
return Description;
}
public string returnTranslation()
{
return Translation;
}
public void CreateNewFlashcard()
{
Console.Write ("Word => ");
Word = Console.ReadLine();
Word = Word.ToLower();
Console.Write("Description => ");
Description = Description = Console.ReadLine();
Description = Description.ToLower();
Console.Write("Translation => ");
Translation = Console.ReadLine();
Translation = Translation.ToLower();
IsKnownTemporarly = false;
Console.Clear();
}
public void DisplayFlaschard()
{
Console.WriteLine(Word + " means " + Translation + " [" + Description + "]");
Console.ReadKey();
}
public void GuessWord()
{
Console.WriteLine("Do you remember this one? [" + Word + "]");
string userInput = Console.ReadLine();
if (userInput.ToLower() == Translation)
{
this.IsKnownTemporarly = true;
Console.WriteLine("Indeed, that is correct!");
Console.ReadKey();
Console.Clear();
}
else
{
Console.WriteLine("I'll help you this time, try to memorize!");
Console.WriteLine(Word + " means " + Translation + " [" + Description + "]");
this.IsKnownTemporarly = false;
Console.ReadKey();
Console.Clear();
}
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace FlashCardApp
{
class Program
{
static void Main(string[] args)
{
List<Flashcard> FlashcardsList = new List<Flashcard>();
Flashcard flashcard1 = new Flashcard("Car", "auto" ,"it drives
through streets");
Flashcard flashcard2 = new Flashcard("street", "droga" , "Lead you
around cities");
Flashcard flashcard3 = new Flashcard("screen", "ekran", "It displays
info");
Flashcard flashcard4 = new Flashcard("stapler", "zszywacz",
"costam");
Flashcard flashcard5 = new Flashcard("paper", "papier", "costam");
Flashcard flashcard6 = new Flashcard("pen", "dlugopis", "dligpsfs");
FlashcardsList.Add(flashcard1);
FlashcardsList.Add(flashcard2);
FlashcardsList.Add(flashcard3);
FlashcardsList.Add(flashcard4);
FlashcardsList.Add(flashcard5);
FlashcardsList.Add(flashcard6);
ConnectDB();
}
public static void ConnectDB()
{
string connectionString;
SqlConnection conn;
connectionString = #"Data Source=DESKTOP-RDM63QN\SQLEXPRESS; Initial
Catalog=Fishcards; User ID=MyName ;Password=MyPassword" ;
conn = new SqlConnection(connectionString);
conn.Open();
Console.WriteLine("Done!");
conn.Close();
}
public static void AddNewFlaschards(List<Flashcard> FlashcardsList)
{
Console.WriteLine("ADD NEW FLASCHARDS!");
Console.WriteLine("How many would you like to add?");
int count = Convert.ToInt32(Console.ReadLine());
Console.Clear();
for (int i = 0; i < count; i++)
{
Flashcard flashcard = new Flashcard();
Console.WriteLine("No. " + (i+1));
flashcard.CreateNewFlashcard();
FlashcardsList.Add(new Flashcard(flashcard));
}
Console.Read();
Console.Clear();
}
public static void ReviseFlashcards(List<Flashcard> FlashcardsList)
{
Console.WriteLine("REVISE YOUR SAVED FLASHCARDS!");
FlashcardsList.ForEach(fl => fl.DisplayFlaschard());
Console.Read();
Console.Clear();
}
public static bool IsThereAnyUnknownLeft(List<Flashcard> FlashcardsList)
{
int var = FlashcardsList.Count; // Merging the size of FlashcardList
int i = 0;
int sum = 0;
int[] array = new int[var];
foreach (Flashcard flashcard in FlashcardsList)
{
if(flashcard.IsKnownTemporarly == false)
{
array[i] = 0;
}
else
{
array[i] = 1;
}
i++;
}
for(int a = 0; a<var; a++)
{
sum = sum + array[a];
}
if (sum == var)
return true;
else
return false;
}
public static void PlayGuessingGame(List<Flashcard> FlashcardsList)
{
while(!IsThereAnyUnknownLeft(FlashcardsList))
{
foreach (Flashcard flashcard in FlashcardsList.Where(flashcard
=> flashcard.IsKnownTemporarly == false))
{
flashcard.GuessWord();
}
}
Console.Read();
Console.Clear();
}
}
}
Problem is that Visual Studio returns an error on conn.Open() with this info:
System.Data.SqlClient.SqlException: Cannot open database "Fishcards" requested by the login. The login failed.
Login failed for user 'MyNameisHere'.

Unity C# GraphQL Post Request Body Authentication

I am working on trying to connect to my GraphQL server my developers have setup from within Unity. I have found some scripts to help with this process, however, I am still not able to connect because i need to be logged into the system hosting graphql to be able to query externally, I cannot just use the endpoint url.
My developer has told me to do a POST request to mysystem/login and in the request body add {email: string, password: string}. I have tried a few different things and nothing is working. I have to log into the mysystem/login with email and password, then i will be able to connect to mygraphql endpoint from the code below.--i was assuming this portion would go where I have the //smt authentication notes. Any help on how to setup the post request and where it should be or how it should work would be much appreciated.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using SimpleJSON;
using UnityEngine;
using UnityEngine.Networking;
namespace graphQLClient
{
public class GraphQuery : MonoBehaviour
{
public static GraphQuery instance = null;
[Tooltip("The url of the node endpoint of the graphQL server being queried")]
public static string url;
public delegate void QueryComplete();
public static event QueryComplete onQueryComplete;
public enum Status { Neutral, Loading, Complete, Error };
public static Status queryStatus;
public static string queryReturn;
string authURL;
public static string LoginToken;
public class Query
{
public string query;
}
public void Awake()
{
if (instance == null)
{
instance = this;
}
else if (instance != this)
{
Destroy(gameObject);
}
DontDestroyOnLoad(gameObject);
StartCoroutine("PostLogin");
}
private void Start()
{
LoginToken = "";
}
public static Dictionary<string, string> variable = new Dictionary<string, string>();
public static Dictionary<string, string[]> array = new Dictionary<string, string[]>();
// Use this for initialization
// SMT Authentication to ELP
// SMT Needed for Authentication--- if (token != null) request.SetRequestHeader("Authorization", "Bearer " + token);
//In the request body: {email: string, password: string}
//You’ll either get a 401 with an empty response or 201 with {token: string, user: object}
IEnumerator PostLogin()
{
Debug.Log("Logging in...");
string authURL = "https://myapp.com/login";
string loginBody = "{\"email\":\"myemail.com\",\"password\":\"mypassowrd\"}";
var request = new UnityWebRequest(authURL, "POST");
byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(loginBody);
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
{
Debug.Log("Login error!");
foreach (KeyValuePair<string, string> entry in request.GetResponseHeaders())
{
Debug.Log(entry.Value + "=" + entry.Key);
}
Debug.Log(request.error);
}
else
{
Debug.Log("Login complete!");
//Debug.Log(request.downloadHandler.text);
LoginToken = request.downloadHandler.text;
Debug.Log(LoginToken);
}
}
public static WWW POST(string details)
{
//var request = new UnityWebRequest(url, "POST");
details = QuerySorter(details);
Query query = new Query();
string jsonData = "";
WWWForm form = new WWWForm();
query = new Query { query = details };
jsonData = JsonUtility.ToJson(query);
byte[] postData = Encoding.ASCII.GetBytes(jsonData);
Dictionary<string, string> postHeader = form.headers;
//postHeader["Authorization"] = "Bearer " + downloadHandler.Token;
if (postHeader.ContainsKey("Content-Type"))
//postHeader["Content-Type"] = "application/json";
postHeader.Add("Authorization", "Bearer " + LoginToken);
else
//postHeader.Add("Content-Type", "application/json");
postHeader.Add("Authorization", "Bearer " + LoginToken);
WWW www = new WWW(url, postData, postHeader);
instance.StartCoroutine(WaitForRequest(www));
queryStatus = Status.Loading;
return www;
}
static IEnumerator WaitForRequest(WWW data)
{
yield return data; // Wait until the download is done
if (data.error != null)
{
Debug.Log("There was an error sending request: " + data.error);
queryStatus = Status.Error;
}
else
{
queryReturn = data.text;
queryStatus = Status.Complete;
}
onQueryComplete();
}
public static string QuerySorter(string query)
{
string finalString;
string[] splitString;
string[] separators = { "$", "^" };
splitString = query.Split(separators, StringSplitOptions.RemoveEmptyEntries);
finalString = splitString[0];
for (int i = 1; i < splitString.Length; i++)
{
if (i % 2 == 0)
{
finalString += splitString[i];
}
else
{
if (!splitString[i].Contains("[]"))
{
finalString += variable[splitString[i]];
}
else
{
finalString += ArraySorter(splitString[i]);
}
}
}
return finalString;
}
public static string ArraySorter(string theArray)
{
string[] anArray;
string solution;
anArray = array[theArray];
solution = "[";
foreach (string a in anArray)
{
}
for (int i = 0; i < anArray.Length; i++)
{
solution += anArray[i].Trim(new Char[] { '"' });
if (i < anArray.Length - 1)
solution += ",";
}
solution += "]";
Debug.Log("This is solution " + solution);
return solution;
}
}
}

Implementing Overrides in Bloomberg C# API

In querying "YAS_YLD_SPREAD" for multiple securities, I am trying to assign a different override value for the "YAS_BOND_PX" override of each (as per Excel snapshot)
However, I am doing something wrong in assigning the overrides, as the output does not return a single "YAS_YLD_SPREAD" for each security (it also spuriously returns a "YAS_YLD_SPREAD 1") and the values returned are not the 100.21, 645.06 values I expect/need
Grateful for your help,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ArrayList = System.Collections.ArrayList;
using Event = Bloomberglp.Blpapi.Event;
using Element = Bloomberglp.Blpapi.Element;
using Message = Bloomberglp.Blpapi.Message;
using Name = Bloomberglp.Blpapi.Name;
using Request = Bloomberglp.Blpapi.Request;
using Service = Bloomberglp.Blpapi.Service;
using Session = Bloomberglp.Blpapi.Session;
using SessionOptions = Bloomberglp.Blpapi.SessionOptions;
using InvalidRequestException =
Bloomberglp.Blpapi.InvalidRequestException;
using Subscription = Bloomberglp.Blpapi.Subscription;
namespace COATI
{
public class BloombergFetch
{
public string[] IsinArray;
private const String APIREFDATA_SVC = "//blp/refdata";
private static readonly Name SECURITY_DATA =
Name.GetName("securityData");
private static readonly Name SECURITY = Name.GetName("security");
private static readonly Name FIELD_DATA = Name.GetName("fieldData");
private static readonly Name RESPONSE_ERROR =
Name.GetName("responseError");
private static readonly Name SECURITY_ERROR =
Name.GetName("securityError");
private static readonly Name FIELD_EXCEPTIONS =
Name.GetName("fieldExceptions");
private static readonly Name FIELD_ID = Name.GetName("fieldId");
private static readonly Name ERROR_INFO = Name.GetName("errorInfo");
private static readonly Name CATEGORY = Name.GetName("category");
private static readonly Name MESSAGE = Name.GetName("message");
private ArrayList d_securities = new ArrayList();
private ArrayList d_fields = new ArrayList();
private ArrayList d_overrides = new ArrayList();
private ArrayList d_overridevalues = new ArrayList();
static void Main()
{
BloombergFetch example = new BloombergFetch();
example.run();
System.Console.WriteLine("Press ENTER to quit");
System.Console.Read();
}
public void run()
{
string serverHost = "localhost";
int serverPort = 8194;
SessionOptions sessionOptions = new SessionOptions();
sessionOptions.ServerHost = serverHost;
sessionOptions.ServerPort = serverPort;
System.Console.WriteLine("Connecting to " + serverHost + ":" +
serverPort);
Session session = new Session(sessionOptions);
bool sessionStarted = session.Start();
if (!sessionStarted)
{
System.Console.Error.WriteLine("Failed to start session.");
return;
}
d_securities.Add("XS0975256685 Corp");
d_securities.Add("XS1207058733 Corp");
d_fields.Add("YAS_YLD_SPREAD");
d_fields.Add("YAS_YLD_SPREAD");
d_overrides.Add("YAS_BOND_PX"); d_overridevalues.Add(116);
d_overrides.Add("YAS_BOND_PX"); d_overridevalues.Add(88);
try
{
sendRefDataRequest(session);
}
catch (InvalidRequestException e)
{
System.Console.WriteLine(e.ToString());
}
// wait for events from session.
eventLoop(session);
session.Stop();
*/
}
private void sendRefDataRequest(Session session)
{
if (!session.OpenService(APIREFDATA_SVC))
{
System.Console.Error.WriteLine("Failed to open service: " +
APIREFDATA_SVC);
return;
}
Service refDataService = session.GetService(APIREFDATA_SVC);
Request request = refDataService.CreateRequest("ReferenceDataRequest");
Element securities = request.GetElement("securities");
Element overrides = request.GetElement("overrides");
for (int i = 0; i < d_securities.Count; ++i)
{
securities.AppendValue((string)d_securities[i]);
}
Element fields = request.GetElement("fields");
for (int i = 0; i < d_fields.Count; ++i)
{
fields.AppendValue((string)d_fields[i]);
}
for (int i = 0; i < d_overrides.Count; ++i)
{
Element bboverride = overrides.AppendElement();
bboverride.SetElement("fieldId",d_overrides[i].ToString());
//bboverride.SetElement("fieldId", "YAS_BOND_PX");
bboverride.SetElement("value", Convert.ToBoolean(d_overridevalues[i]));
//bboverride.SetElement("value", 100);
}
System.Console.WriteLine("Sending Request: " + request);
session.SendRequest(request, null);
}
private void eventLoop(Session session)
{
bool done = false;
while (!done)
{
Event eventObj = session.NextEvent();
if (eventObj.Type == Event.EventType.PARTIAL_RESPONSE)
{
System.Console.WriteLine("Processing Partial Response");
processResponseEvent(eventObj);
}
else if (eventObj.Type == Event.EventType.RESPONSE)
{
System.Console.WriteLine("Processing Response");
processResponseEvent(eventObj);
done = true;
}
else
{
foreach (Message msg in eventObj.GetMessages())
{
System.Console.WriteLine(msg.AsElement);
if (eventObj.Type == Event.EventType.SESSION_STATUS)
{
if (msg.MessageType.Equals("SessionTerminated"))
{
done = true;
}
}
}
}
}
}
private void processResponseEvent(Event eventObj)
{
foreach (Message msg in eventObj.GetMessages())
{
if (msg.HasElement(RESPONSE_ERROR))
{
System.Console.WriteLine("REQUEST FAILED: " +
msg.GetElement(RESPONSE_ERROR));
continue;
}
Element securities = msg.GetElement(SECURITY_DATA);
int numSecurities = securities.NumValues;
System.Console.WriteLine("Processing " + numSecurities + " securities:");
for (int i = 0; i < numSecurities; ++i)
{
Element security = securities.GetValueAsElement(i);
string ticker = security.GetElementAsString(SECURITY);
System.Console.WriteLine("\nTicker: " + ticker);
if (security.HasElement("securityError"))
{
System.Console.WriteLine("\tSECURITY FAILED: " +
security.GetElement(SECURITY_ERROR));
continue;
}
Element fields = security.GetElement(FIELD_DATA);
if (fields.NumElements > 0)
{
System.Console.WriteLine("FIELD\t\tVALUE");
System.Console.WriteLine("-----\t\t-----");
int numElements = fields.NumElements;
for (int j = 0; j < numElements; ++j)
{
Element field = fields.GetElement(j);
System.Console.WriteLine(field.Name + "\t\t" +
field.GetValueAsString());
}
}
else System.Console.WriteLine("No fields");
}
}
}
}
}
I haven't read your code in detail but one obvious issue is that if you want to use a different overriden value for the two securities, you need to submit two separate requests.
If you submit one request for XS0975256685 only with the YAS_BOND_PX override set to 116, you should get the desired result (I got 101.8739 a minute ago which matches Excel's result at the same moment).
Also note that the returned value does change with the market so you may get different values at each run: refresh your Excel spreadsheet at the same time if you want to verify that the data match.

Categories