Make SQL Calls on WindowsServices - c#
I'm making an application as follows: I have a webservice running on a local server, this webservice returns json like this:
[{"Id":1,"Titulo":"Live to win","Link":"https://www.youtube.com/embed/DPHlGVe8wxI","BandaId":1,"BandaNome":"Paul Stanley","GeneroId":1,"GeneroNome":"Rock","DtCriacao":"2017-03-23T16:42:54","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":false},{"Id":2,"Titulo":"Welcome to the jungle","Link":null,"BandaId":2,"BandaNome":"Guns n´ roses","GeneroId":1,"GeneroNome":"Rock","DtCriacao":"2017-03-23T16:42:54","CriadorId":2,"CriadorNome":"Usuário Teste","Ativo":true},{"Id":3,"Titulo":"Something just like this","Link":null,"BandaId":3,"BandaNome":"The Chainsmokers","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":true},{"Id":4,"Titulo":"Beliver","Link":null,"BandaId":4,"BandaNome":"Imagine Dragons","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":true},{"Id":5,"Titulo":"Radioactive","Link":null,"BandaId":4,"BandaNome":"Imagine Dragons","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":true},{"Id":6,"Titulo":"Friends - Original Mix","Link":null,"BandaId":5,"BandaNome":"Steener","GeneroId":2,"GeneroNome":"EDM","DtCriacao":"2017-03-23T16:42:54","CriadorId":2,"CriadorNome":"Usuário Teste","Ativo":true},{"Id":7,"Titulo":"Amanheceu","Link":null,"BandaId":6,"BandaNome":"Scalene","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":2,"CriadorNome":"Usuário Teste","Ativo":true},{"Id":8,"Titulo":"Sonhador II","Link":null,"BandaId":6,"BandaNome":"Scalene","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":2,"CriadorNome":"Usuário Teste","Ativo":true},{"Id":9,"Titulo":"Amianto","Link":null,"BandaId":7,"BandaNome":"Supercombo","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":true},{"Id":10,"Titulo":"Monstros","Link":null,"BandaId":7,"BandaNome":"Supercombo","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":true},{"Id":11,"Titulo":"Piloto Automático","Link":null,"BandaId":7,"BandaNome":"Supercombo","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":2,"CriadorNome":"Usuário Teste","Ativo":true},{"Id":12,"Titulo":"Eutanásia","Link":null,"BandaId":7,"BandaNome":"Supercombo","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-23T16:42:54","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":true},{"Id":13,"Titulo":"Shots - Broiler Remix","Link":null,"BandaId":4,"BandaNome":"Imagine Dragons","GeneroId":3,"GeneroNome":"Indie","DtCriacao":"2017-03-24T16:55:46","CriadorId":1,"CriadorNome":"Márcio Eric","Ativo":true}]
But now I need to create a Windows Services that communicates with this WebService and what it receives in a database, I spent all day doing this webservice in several ways, but I did not find anything about good practices with webservices or etc. I'll show you what I did, but I'd like some tips on windows services, thank you
Here is my code
Service:
private Timer _worker;
private readonly int _interval = Convert.ToInt32(ConfigurationManager.AppSettings["timer"]);
private readonly string _connection = ConfigurationManager.AppSettings["connection"];
//private readonly Connector _usuarioConnector;
private readonly Connector _bandaConnector;
//private readonly Connector _generoConnector;
private readonly Connector _musicaConnector;
private SqlConnection conn;
public Service1()
{
//_usuarioConnector = new Connector("UsuarioBase");
_bandaConnector = new Connector("BandaBase");
//_generoConnector = new Connector("GeneroBase");
_musicaConnector = new Connector("MusicaBase");
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_worker = new Timer((Update), null, 0, _interval);
}
protected override void OnStop()
{
}
private void Update(Object state)
{
using (SqlConnection connection = new SqlConnection(
_connection))
{
SqlCommand command = new SqlCommand("insert into Genero(nome, descricao, dtcriacao, criadorid, ativo) values('teste', 'teste', getdate(), 1, 1)", connection);
command.Connection.Open();
command.ExecuteNonQuery();
EventLog.WriteEntry("Query executada", EventLogEntryType.Warning);
}
}
Loader
public class Loader
{
public static List<Usuario> LoadUsuarios(Connector usuarioConnector)
{
return (List<Usuario>)Newtonsoft.Json.JsonConvert.DeserializeObject(usuarioConnector.GetData(), typeof(List<Usuario>));
}
public static List<Banda> LoadBandas(Connector bandaConnector)
{
var bandasDtos = (List<BandaDto>)Newtonsoft.Json.JsonConvert.DeserializeObject(bandaConnector.GetData(), typeof(List<BandaDto>));
return bandasDtos.Select(dto => dto.ConvertToBanda()).ToList();
}
//public static List<Genero> LoadGeneros(Connector generoConnector)
//{
//var musicasDtos = (List<MusicaDto>)Newtonsoft.Json.JsonConvert.DeserializeObject(musicaConnector.GetData(), typeof(List<MusicaDto>));
//return musicasDtos.Select(dto => dto.ConvertToMusica()).ToList();
//}
public static List<Musica> LoadMusicas(Connector musicaConnector)
{
var musicasDtos = (List<MusicaDto>)Newtonsoft.Json.JsonConvert.DeserializeObject(musicaConnector.GetData(), typeof(List<MusicaDto>));
return musicasDtos.Select(dto => dto.ConvertToMusica()).ToList();
}
}
Connector
private string Host { get; }
private WebRequest _request;
public WebResponse Response;
public string ConnectionStatus;
private Stream _dataStream;
private StreamReader _reader;
public Connector(string config)
{
Host = ConfigurationManager.AppSettings[config];
}
public string GetData()
{
StartConnection();
_dataStream = Response.GetResponseStream();
_reader = new StreamReader(_dataStream);
var toReturn = _reader.ReadToEnd();
EndConnection();
return toReturn;
}
private void StartConnection()
{
_request = WebRequest.Create(Host);
_request.Credentials = CredentialCache.DefaultCredentials;
Response = _request.GetResponse();
ConnectionStatus = (((HttpWebResponse)Response).StatusDescription);
}
private void EndConnection()
{
_reader.Close();
Response.Close();
}
Edit1 In the current code it is doing a select, however in what I intend to do it will do inserts
I discovered, unfortunately the timer was not working, so I just changed it to a thread.
Related
My Application throws an error when it starts at the same time as windows (Selenium)
I hope you are well, I need help, I am creating a software that starts at the same time as Windows with Selenium, this software opens a web browser in the background, but when the computer starts, I get this error: But if I open my app again it works. How can I make it runs at the same time as Windows? //register the application key private void Start() { RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); if (rkApp.GetValue(Application.ProductName, Application.ExecutablePath.ToString()) != null) { rkApp.SetValue(Application.ProductName, Application.ExecutablePath.ToString()); } } private Dictionary<string, WebExplorer > _WebExplorer = new Dictionary<string, WebExplorer >() { ["chrome"] = new ChromeWebExplorer(), ["firefox"] = new FireFoxWebExplorer(), ["edge"] = new MicrosoftEdgeWebExplorer() }; private DriverManager _Mananger = new DriverManager(); private IWebDriver _Driver; public WebDriver(string WebExplorer , string Version) { Init(WebExplorer , Version); } private void Init(string WebExplorer , string Version) { _Mananger.SetUpDriver(_WebExplorer [WebExplorer].GetConfig(), Version); _WebExplorer[WebExplorer].Start().HideCommandPromptWindow = true; _Driver = Navegadores[WebExplorer].GetDriver(); } //A web explorer class internal class MicrosoftEdgeWebExplorer: WebExplorer { public MicrosoftEdgeWebExplorer() { _Options= new EdgeOptions(); } public override IDriverConfig GetConfig() { return new EdgeConfig(); } public override IWebDriver GetDriver() { var Options = _Options as EdgeOptions; Opciones.AddArguments(_Arguments); return new EdgeDriver(_Service as EdgeDriverService,Options); } public override DriverService StartService() { _Service= EdgeDriverService.CreateDefaultService(); return _Service; } }
Make Check Internet Async win Webclient.Openread
My apps in xamarin form is populate by a json file i download online then i need to be sure device have internet access. I try this but it freeze UI and timeout not seam to be used then i like to make it async. private void CheckClicked(object sender, EventArgs e) { if (CheckForInternetConnection() == true) { isinternet.Text = "Internet ok"; } else { isinternet.Text = "Internet down"; } } public static bool CheckForInternetConnection() { try { using (var client = new MyWebClient(5000)) using (client.OpenRead("http://google.com/generate_204")) return true; } catch { return false; } } with this class public class MyWebClient : WebClient { private int timeout; public int Timeout { get { return timeout; } set { timeout = value; } } public MyWebClient() { this.timeout = 10000; } public MyWebClient(int timeout) { this.timeout = timeout; } }
You should use HttpClient and the asynchronous methods it implements. Try to stay away from legacy HTTP client implementations such as WebClient. A quick example would be: private static readonly HttpClient _httpClient = new HttpClient(); private async void CheckClicked(object sender, EventArgs e) { var isConnected = await CheckForInternetConnectionAsync(); if(isConnected) { isinternet.Text = "Internet ok"; } else { isinternet.Text = "Internet down"; } } private static async Task<bool> CheckForInternetConnectionAsync() { using(var tokSource = new CancellationTokenSource(5000)) { try { await _httpClient.GetAsync("https://www.example.com", tokSource.Token); } catch(OperationCanceledException) { return false; } } return true; } This will leave your UI responsive, but at the same time accomplish making a request.
ASP static database connection
I have the following code in a Connection class private static SqlConnection m_con { get { var maxPriv = GetMaximumPrivelegeLvl(); if (maxPriv > m_currentPrivelegeLvl) { m_instance = new Connection(maxPriv); } return m_instance.m_databaseConnection; } } private readonly SqlConnection m_databaseConnection; Will this be thread safe ?
Reconnect vpn. Windows service
I've been trying to implement a windows service that would keep vpn connection alive. I've found that it is possible to achieve using DotRas library by subscribing to RasConnectionWatcher.Disconnected event: public class SampleService { public SampleService() { this.shutdownEvent = new ManualResetEvent(false); this.connectionWatcher = new RasConnectionWatcher(); this.connectionWatcher.Disconnected += onVpnDisconnected; } // redial void onVpnDisconnected(Object sender, RasConnectionEventArgs e) { this.DialUp(); } void DialUp() { // connection setup is omitted // keep the handle of the connection this.connectionWatcher.Handle = dialer.Dial(); } public void Start() { this.thread = new Thread(WorkerThreadFunc); this.thread.IsBackground = true; this.thread.Start(); } public void Stop() { this.shutdownEvent.Set(); if(!this.thread.Join(3000)) this.thread.Abort(); } private void WorkerThreadFunc() { this.DialUp(); while(!this.shutdownEvent.WaitOne(0)) Thread.Sleep(1000); } } When I start the service vpn connection opens without any problem, but when I manually interrupt the connection it seems that Disconnected event doesn't fire up.
solution 1 Found similar question/answer here: http://social.msdn.microsoft.com/Forums/en-US/56ab2d0d-2425-4d76-81fc-04a1e1136141/ras-connection-application-and-service?forum=netfxnetcom. solution 2 Got an answer from Jeff Winn yesterday: https://dotras.codeplex.com/discussions/547038 public class VpnKeeperService : IService { private ManualResetEvent shutdownEvent; private RasConnectionWatcher connWatcher; private Thread thread; public VpnKeeperService() { this.shutdownEvent = new ManualResetEvent(false); this.connWatcher = new RasConnectionWatcher(); this.connWatcher.EnableRaisingEvents = true; this.connWatcher.Disconnected += (s, args) => { this.DialUp(); }; } Boolean DialUp() { try { using(var phoneBook = new RasPhoneBook()) { var name = VpnConfig.GetConfig().ConnectionName; var user = VpnConfig.GetConfig().Username; var pass = VpnConfig.GetConfig().Password; var pbPath = VpnConfig.GetConfig().PhoneBookPath; phoneBook.Open(pbPath); var entry = phoneBook.Entries.FirstOrDefault(e => e.Name.Equals(name)); if(entry != null) { using(var dialer = new RasDialer()) { dialer.EntryName = name; dialer.Credentials = new NetworkCredential(user, pass); dialer.PhoneBookPath = pbPath; dialer.Dial(); } } else throw new ArgumentException( message: "entry wasn't found: " + name, paramName: "entry" ); } return true; } catch { // log the exception return false; } } public void Start() { this.thread = new Thread(WorkerThreadFunc); this.thread.Name = "vpn keeper"; this.thread.IsBackground = true; this.thread.Start(); } public void Stop() { this.shutdownEvent.Set(); if(!this.thread.Join(3000)) { this.thread.Abort(); } } private void WorkerThreadFunc() { if(this.DialUp()) { while(!this.shutdownEvent.WaitOne(0)) { Thread.Sleep(1000); } } } } Hope it helps someone.
C# Async WebRequests: Perform Action When All Requests Are Completed
I have this basic scraping console application in C# that Asynchronously uses WebRequest to get html from a list of sites. It works fine, but how do I set up a trigger that goes off when every site in the list has been processed? I've spent a couple hours researching various solutions online, including the MS docs, but none of them provide a straight forward answer via code. I've read about the IAsyncResult.AsyncWaitHandle but I have no clue how to integrate it into my code. I'd just like to call a custom function when all threads complete processing or timeout. One trick is that I never know ahead of time how many sites are in my list (it's user defined), so I need a solution that's robust enough to wait for 5 events for 100,000 events to complete. Thanks. Working code below: using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Threading; namespace AsyncApp_01 { class Program { static void Main(string[] args) { ArrayList alSites = new ArrayList(); alSites.Add("http://www.google.com"); alSites.Add("http://www.lostspires.com"); ScanSites(alSites); Console.Read(); } private static void ScanSites(ArrayList sites) { foreach (string uriString in sites) { WebRequest request = HttpWebRequest.Create(uriString); request.Method = "GET"; object data = new object(); //container for our "Stuff" // RequestState is a custom class to pass info to the callback RequestState state = new RequestState(request, data, uriString); IAsyncResult result = request.BeginGetResponse(new AsyncCallback(UpdateItem), state); //Register the timeout callback ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), state, (30 * 1000), true); } } private static void UpdateItem(IAsyncResult result) { // grab the custom state object RequestState state = (RequestState)result.AsyncState; WebRequest request = (WebRequest)state.Request; // get the Response HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); Stream s = (Stream)response.GetResponseStream(); StreamReader readStream = new StreamReader(s); // dataString will hold the entire contents of the requested page if we need it. string dataString = readStream.ReadToEnd(); response.Close(); s.Close(); readStream.Close(); Console.WriteLine(dataString); } private static void ScanTimeoutCallback(object state, bool timedOut) { if (timedOut) { RequestState reqState = (RequestState)state; if (reqState != null) { reqState.Request.Abort(); } Console.WriteLine("aborted- timeout"); } } class RequestState { public WebRequest Request; // holds the request public object Data; // store any data in this public string SiteUrl; // holds the UrlString to match up results (Database lookup, etc). public RequestState(WebRequest request, object data, string siteUrl) { this.Request = request; this.Data = data; this.SiteUrl = siteUrl; } } } } Bonus points for anyone who can also tell me how to limit the number of concurrent threads. For example, if I have 100 sites to process, how do I set it up so that 10 sites get processed at a time, but not more. I don't want to open 100 threads.
Here's a quick sample I threw together. I removed the WebClient implementation, as it seems like you're using the WebRequest one. I'm also making use of .Net 4's ConcurrentBag: public class Scraper { private readonly IEnumerable<string> _sites; private readonly ConcurrentBag<string> _data; private volatile int _count; private readonly int _total; public Scraper(IEnumerable<string> sites) { _sites = sites; _data = new ConcurrentBag<string>(); _total = sites.Count(); } public void Start() { foreach (var site in _sites) { ScrapeSite(site); } } private void ScrapeSite(string site) { var req = WebRequest.Create(site); req.BeginGetResponse(AsyncCallback, req); } private void AsyncCallback(IAsyncResult ar) { Interlocked.Increment(ref _count); var req = ar.AsyncState as WebRequest; var result = req.EndGetResponse(ar); var reader = new StreamReader(result.GetResponseStream()); var data = reader.ReadToEnd(); this.OnSiteScraped(req.RequestUri.AbsoluteUri, data); _data.Add(data); if (_count == _total) { OnScrapingComplete(); } } private void OnSiteScraped(string site, string data) { var handler = this.SiteScraped; if (handler != null) { handler(this, new SiteScrapedEventArgs(site, data)); } } private void OnScrapingComplete() { var handler = this.ScrapingComplete; if (handler != null) { handler(this, new ScrapingCompletedEventArgs(_data)); } } public event EventHandler<SiteScrapedEventArgs> SiteScraped; public event EventHandler<ScrapingCompletedEventArgs> ScrapingComplete; } public class SiteScrapedEventArgs : EventArgs { public string Site { get; private set; } public string Data { get; private set; } public SiteScrapedEventArgs(string site, string data) { this.Site = site; this.Data = data; } } OK, I created some basic classes, and this should do the trick. If this isn't enough, I'm sorry, I simply can't help you: public class RankedPage { public int Rank { get; set; } public string Site { get; set; } } public class WebRequestData { public WebRequest WebRequest { get; set; } public RankedPage Page { get; set; } } public class Scraper { private readonly IEnumerable<RankedPage> _sites; private readonly ConcurrentBag<KeyValuePair<RankedPage,string>> _data; private volatile int _count; private readonly int _total; public Scraper(IEnumerable<RankedPage> sites) { _sites = sites; _data = new ConcurrentBag<KeyValuePair<RankedPage, string>>(); _total = sites.Count(); } public void Start() { foreach (var site in _sites) { ScrapeSite(site); } } private void ScrapeSite(RankedPage site) { var req = WebRequest.Create(site.Site); req.BeginGetResponse(AsyncCallback, new WebRequestData{ Page = site, WebRequest = req}); } private void AsyncCallback(IAsyncResult ar) { Interlocked.Increment(ref _count); var webRequestData = ar.AsyncState as WebRequestData; var req = webRequestData.WebRequest; var result = req.EndGetResponse(ar); var reader = new StreamReader(result.GetResponseStream()); var data = reader.ReadToEnd(); this.OnSiteScraped(webRequestData.Page, data); _data.Add(new KeyValuePair<RankedPage, string>(webRequestData.Page,data)); if (_count == _total) { OnScrapingComplete(); } } private void OnSiteScraped(RankedPage page, string data) { var handler = this.SiteScraped; if (handler != null) { handler(this, new SiteScrapedEventArgs(page, data)); } } private void OnScrapingComplete() { var handler = this.ScrapingComplete; if (handler != null) { handler(this, new ScrapingCompletedEventArgs(_data)); } } public event EventHandler<SiteScrapedEventArgs> SiteScraped; public event EventHandler<ScrapingCompletedEventArgs> ScrapingComplete; } public class SiteScrapedEventArgs : EventArgs { public RankedPage Site { get; private set; } public string Data { get; private set; } public SiteScrapedEventArgs(RankedPage site, string data) { this.Site = site; this.Data = data; } } public class ScrapingCompletedEventArgs : EventArgs { public IEnumerable<KeyValuePair<RankedPage,string >> SiteData { get; private set; } public ScrapingCompletedEventArgs(IEnumerable<KeyValuePair<RankedPage, string>> siteData) { this.SiteData = siteData; } }