How can I call this webservice asynchronously? - c#

In Visual Studio I created a web service (and checked "generate asynchronous operations") on this URL:
http://www.webservicex.com/globalweather.asmx
and can get the data out synchronously but what is the syntax for getting the data out asychronously?
using System.Windows;
using TestConsume2343.ServiceReference1;
using System;
using System.Net;
namespace TestConsume2343
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
GlobalWeatherSoapClient client = new GlobalWeatherSoapClient();
//synchronous
string getWeatherResult = client.GetWeather("Berlin", "Germany");
Console.WriteLine("Get Weather Result: " + getWeatherResult); //works
//asynchronous
client.BeginGetWeather("Berlin", "Germany", new AsyncCallback(GotWeather), null);
}
void GotWeather(IAsyncResult result)
{
//Console.WriteLine("Get Weather Result: " + result.???);
}
}
}
Answer:
Thanks TLiebe, with your EndGetWeather suggestion I was able to get it to work like this:
using System.Windows;
using TestConsume2343.ServiceReference1;
using System;
namespace TestConsume2343
{
public partial class Window1 : Window
{
GlobalWeatherSoapClient client = new GlobalWeatherSoapClient();
public Window1()
{
InitializeComponent();
client.BeginGetWeather("Berlin", "Germany", new AsyncCallback(GotWeather), null);
}
void GotWeather(IAsyncResult result)
{
Console.WriteLine("Get Weather Result: " + client.EndGetWeather(result).ToString());
}
}
}

I suggest using the event provided by the auto-generated proxy instead of messing with the AsyncCallback
public void DoWork()
{
GlobalWeatherSoapClient client = new GlobalWeatherSoapClient();
client.GetWeatherCompleted += new EventHandler<WeatherCompletedEventArgs>(client_GetWeatherCompleted);
client.GetWeatherAsync("Berlin", "Germany");
}
void client_GetWeatherCompleted(object sender, WeatherCompletedEventArgs e)
{
Console.WriteLine("Get Weather Result: " + e.Result);
}

In your GotWeather() method you need to call the EndGetWeather() method. Have a look at some of the sample code at MSDN. You need to use the IAsyncResult object to get your delegate method so that you can call the EndGetWeather() method.

Related

Xamarin ContentObserver

trying to get a content observer to work in Xamarin Android.
It's not currently being executed when an event happens.
I tried converting from a java example and fixed it up for c#
I know there is not code to implement the event mod yet, trying to see it get caught first then will add the code.
This is the observer:
using System;
using Android.Database;
using Android.OS;
using Android.Content;
namespace FileTest
{
public class MyObserver : ContentObserver
{
private readonly Android.Net.Uri _uri;
public MyObserver(Android.Net.Uri uri): base(null)
{
_uri = uri;
}
public override void OnChange(bool selfChange) {
this.OnChange (selfChange, null);
Console.WriteLine ("change that I caught " );
}
// public override void OnChange(bool selfChange, Uri uri) {
//
// Console.WriteLine ("change that I caught " );
//
//}
}
}
this is the call:
ContentObserver observer = new MyObserver(Android.Net.Uri.Parse("content://com.Test/databases/Data.db"));
// TODO Auto-generated method stub
var a = Android.Net.Uri.Parse ("content://com.Test/databases/Data.db");
ContentResolver.RegisterContentObserver(a, false, observer);

The calling thread cannot access this object because a different thread owns it (in v4.5)

I am aware that there are plenty questions have been already asked on this. But the solutions provided about delegates is not what I am getting to work with my code because I am working on 4.5 version and looks like the Dispatcher methods have slightly changed. Added to that, I am touching dotnet nearly after a decade and c# for the first time.
What I am actually tying to do in my WPF project is to append text of the textbox inside the main window to display the status/log. This is inside the singleton class called Logger The main static function of this class is log() which accepts a string which needs to be added to the text box with one simple line
txt.AppendText(msg);
After doing some research I changed it to
Dispatcher.CurrentDispatcher.Invoke(() =>
{
txt.AppendText(msg);
});
But I still get the same error. What is going wrong here? Is there anything else to do? Because I am calling this Logger.log() from FileSystemEventHandler insider another singleton class.
private void somethingChanged(object sender, FileSystemEventArgs e)
{
Logger.log("File: " + e.FullPath + " " + e.ChangeType);
}
Below is my Logger class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Threading;
namespace httpclientui.comps
{
class Logger
{
private static TextBox txt;
private Logger() { }
public static void setup(TextBox t){
txt = t;
}
public static void clear()
{
if (txt == null)
{
return;
}
txt.Clear();
}
public static void log(String msg, bool addNewLineChar = true)
{
if (txt == null)
{
return;
}
Dispatcher.CurrentDispatcher.Invoke(() => {
txt.AppendText(msg);
});
}
}
}
This is my main window with only one textbox control called txtMessage.
public partial class MainWindow : Window
{
private String folderToWatch;
public MainWindow()
{
InitializeComponent();
initialize();
}
private void initialize()
{
Logger.setup(txtMessage);
Logger.clear();
Logger.log("Launched");
folderToWatch = "E:\\folder\\subfolder";
Watcher.Instance.setup(folderToWatch);
Watcher.Instance.start();
}
}
}
Below is my Watcher class which has FileSystemWatcher object to keep watching one of the folder and whenever something happens inside that folder like adding/deleting files and renaming the files will needs to be logged inside that textbox.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace httpclientui.comps
{
class Watcher
{
private String path;
//https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
private FileSystemWatcher dog;
private static Watcher instance;
private Watcher()
{
//dog = new FileSystemWatcher()
}
public static Watcher Instance
{
get
{
if (instance == null)
{
instance = new Watcher();
}
return instance;
}
}
public void setup(String folderPath)
{
path = folderPath;
dog = new FileSystemWatcher(folderPath);
Logger.log("setting up to watch folder: " + folderPath);
dog.Changed += new FileSystemEventHandler(somethingChanged);
dog.Created += new FileSystemEventHandler(somethingChanged);
dog.Deleted += new FileSystemEventHandler(somethingChanged);
dog.Renamed += new RenamedEventHandler(somethingRenamed);
}
public void start()
{
Logger.log("starting to watch folder");
dog.EnableRaisingEvents = true;
}
public void pause()
{
dog.EnableRaisingEvents = false;
}
public void stop()
{
dog.EnableRaisingEvents = false;
}
private void somethingChanged(object sender, FileSystemEventArgs e)
{
Logger.log("File: " + e.FullPath + " " + e.ChangeType);
}
private void somethingRenamed(object sender, RenamedEventArgs e)
{
Logger.log("File: " + e.OldFullPath + " renamed to " + e.FullPath);
}
}
}
At first glance, it looks like you are not marshalling the Clear() method call to the Dispatcher. That's what is likely throwing the exception- all access to DispatcherObjects (which includes all Controls) must be done by the Dispatcher thread.
Also, you want to use Application.Current.Dispatcher, not Dispatcher.CurrentDispatcher. The latter just spins up a new Dispatcher on the current (background) thread, which is not what you want.

Skype API Message output

How can I receive and output message from Skype to my application (textbox1.Text)?
I was looking for it in skype4com documentation but didn't find anything.
To listen for chat messages you can do something like this:
//First make a reference to skype4com, probably in here: C:\Program Files (x86)\Common Files\Skype
//Then use the following code:
using System;
using System.Windows.Forms;
using SKYPE4COMLib;
namespace Skype
{
public partial class Form1 : Form
{
private SKYPE4COMLib.Skype skype;
public Form1()
{
InitializeComponent();
skype = new SKYPE4COMLib.Skype();
skype.Attach(7, false);
skype.MessageStatus += new _ISkypeEvents_MessageStatusEventHandler(skype_MessageStatus);
}
private void skype_MessageStatus(ChatMessage msg, TChatMessageStatus status)
{
string message = msg.Sender + ": " + msg.Body;
listBox1.Items.Add(message);
}
}
}

Windows form loads then quits

I'm creating a checkout system for a supermarket. It consists of a checkout, server and MIS program an operates WCF services between them. The problem I have is that the checkout program, which is a windows form, does a few neccessaries in it's application_load method and then just quits.
Here's the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CheckoutLibrary;
using Checkout.ServerLibraryService;
using Checkout.MarketService;
namespace Checkout
{
public partial class theForm : Form
{
private static int checkoutID = 3;
private Product[] allProducts;
public theForm()
{
InitializeComponent();
}
private void theForm_Load(object sender, EventArgs e)
{
// First cache all products
SupermarketServiceSoapClient marketService = new SupermarketServiceSoapClient();
allProducts = marketService.GetAllProducts();
// Load the service provided by the server
ServiceClient serverService = new ServiceClient();
// Load the event handlers for the bar code scanner
BarcodeScanner scanner = new BarcodeScanner();
scanner.ItemScanned += new BarcodeScanner.ItemScannedHandler(scanner_ItemScanned);
scanner.AllItemsScanned += new BarcodeScanner.AllItemsScannedHandler(scanner_AllItemsScanned);
scanner.Start(checkoutID);
}
void scanner_AllItemsScanned(EventArgs args)
{
throw new NotImplementedException();
}
void scanner_ItemScanned(ScanEventArgs args)
{
itemTextBox.Text = "Scanned " + GetItemName(args.Barcode);
}
private void scanItemButton_Click(object sender, EventArgs e)
{
scanner_ItemScanned(new ScanEventArgs(GetRandBarcode()));
}
// A barcode -> product name look up method
public string GetItemName(int barcode)
{
return allProducts[barcode].Description + " # " + allProducts[barcode].Price;
}
// Method to grab a random barcode for simulation
private int GetRandBarcode()
{
Random rand = new Random();
return rand.Next(0,500);
}
}
}
And program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Checkout
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new theForm());
}
}
}
Thanks for any insight.
In WinForms, if your form_load throws an exception, it quits without displaying anything. Annoying, but I'm guessing that's the problem.
You can try a try/catch, or you can hit CTRL+ALT+E and check the Thrown Column for Common Language Runtime Exceptions to see the error.
UPDATE:
Based on comments, here's a sample way to execute something on another thread.
ThreadStart ts = new ThreadStart(() => {
try {
scanner.Start(checkoutID);
} catch {
// Log error
}
});
Thread t = new Thread(ts);
t.Start();

Does WqlEventQuery contain a constructor with 1 argument?

I am trying to create a simple service in C# using VS2008 that creates a text file when the computer goes into sleep mode. My current code throws out the following error:
'SleepNotifierService.WqlEventQuery' does not contain a constructor that takes '1' arguments
Now I looked in the Object browser, and it looks like it does take in one argument. This is what the browser had to say:
public WqlEventQuery(string queryOrEventClassName)
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Management;
using System.IO;
namespace SleepNotifierService
{
public class WqlEventQuery : EventQuery { }
public partial class Service1 : ServiceBase
{
ManagementEventWatcher _watcher;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
_watcher.Start();
}
protected override void OnStop()
{
_watcher.Stop();
}
void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
int eventType = Convert.ToInt32(e.NewEvent.Properties["EventType"].Value);
switch (eventType)
{
case 4:
Sleep();
break;
case 7:
Resume();
break;
}
}
catch (Exception ex)
{
//Log(ex.Message);
}
}
public void Sleep()
{
StreamWriter SW;
SW = File.CreateText("c:\\MyTextFile.txt");
SW.WriteLine("Sleep mode initiated");
SW.Close();
}
public void Resume()
{
}
}
}
Am I interpreting that object browser wrong? I'm new to creating services and C#/.NET in general so it might be something trivial.
Appreciate any help,
Tomek
You're using wrong WqlEventQuery. There's one defined in System.Management and it indeed has a one-argument constructor, but there's also your custom WqlEventQuery class.
If you want to use .NET BCL's class, you'll have to fully qualify it:
var query = new System.Management.WqlEventQuery("Win32_PowerManagementEvent");
or even prefix it with global keyword:
var query = new global::System.Management.WqlEventQuery("Win32_PowerManagementEvent");

Categories

Resources