Using Callback function provided by API, but get no results?(C#) - c#

I'm using a API called WindAPI which provided the financial data from China markets. This API provides a method call wsq() which will provide the RealTime price data to user's program through a callback function!
I write some simple codes in c#,trying to use this wsq() method, but get no results. I wonder there must be some error in codes, but just can't find it!
I'm new to both C# and programming, so if it's a rookie mistake, don't laugh at me:)
Here's the codes, I'll give as much comments as possible, so you can find the misunderstanding in it quickly.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//-----------------------------
using WAPIWrapperCSharp; //the namespace in API dll(official provided)
using WindCommon; //the namespace to process the data formats (official provided)
namespace WSQ2String
{
class WSQ2StringSample
{
static void Main()
{
Console.Write("Begin......");
Console.ReadLine();
//--------------------creat the new API object and log on
WindAPI w = new WindAPI();
Console.WriteLine("New API created!");
w.start();
Console.WriteLine("API log on!");
//--------------------request for the realtime data through w.wsq() method
int errorId = 0;
ulong reqId = w.wsq(ref errorId, "150195.sz", "rt_date, rt_time, rt_lastest", "", myCallback);
Console.WriteLine("errorId = {0}", errorId);
//----adding a control line which will stop the main program and wait for myCallback function to be called
Console.ReadLine(); //after the data arrived, the test is over, and we press a key to let the main program continue
w.cancelRequest(reqId);
w.stop();
Console.Write("End......");
Console.ReadLine();
}
//----
static void myCallback(ulong reqId, WindData wd)
{
Console.WriteLine("wsq data gotback......");
//----transfer the official WindData format to String, and output to the screen
string s = WindDataMethod.WindDataToString(wd, "wsq"); //the method is in WindCommon namespace
Console.Write(s);
}
}
}
My understanding is that, when I request the data service by using w.wsq(), when the prices change(that's the event), myCallback() will be called and export the data on screen!
The reason I add a readline() is to prevent the main program runs too fast, and end before the event(price changing). In that situation, the myCallback() would have no chance to be called!
But when I run the codes, after "errorId = 0" shows, I wait several minutes and still get no results! I confirmed that the price has changed(it usually changed within seconds).
Here is the result I get, and I can't find the reason....(I just type the lines in screen)
>>Begin......
>>New API created!
>>API log on!
>>errorId = 0
and then the prgram just paused there and nothing more happened!
So I'd be very thankful if someone could explain that to me....
Thank you in advanced!
Updated:
According to the comments below, I give the zip files of my solutions.
Also with the API dll and it's source codes.
My solution files and dll
so, anyone help?

Related

In Unity, I want to change the scene and then change the text displayed, but the scene change always happens last

I'm a beginner and this is my first post here so please let me know if I could do anything better.
Using PUN 2 in Unity, I'm trying to return a connection error message when the user attempts to connect to a Photon server but fails.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //Library that provides utilities for scene management
using Photon.Pun; //Library for Photon, provides networking utilities
using Photon.Realtime; //Helps solve problems relating to matchmaking and fast communication
using UnityEngine.UI; //
public class MenuMan : MonoBehaviourPunCallbacks
{
public override void OnDisconnected(DisconnectCause cause) //Callback for when device fails to connect to server. Parameter 'cause' is the cause of this failure
{
Debug.Log("failed :("); // FOR DEBUGGING
Debug.Log(cause); //Prints in the console the cause of this connection failure
DisplayErrorMessage();
}
public Text Message;
public string MessageValue = " ";
public void DisplayErrorMessage() //Method that displays a connection error message to the user
{
SceneManager.LoadScene("Character Select Menu"); //Ensures user is on the Character Select menu
MessageValue = "AAAAAAA";
//Message.text = MessageValue;
Debug.Log(Message.text);
Debug.Log(MessageValue);
}
}
When I run this code, the text "AAAAA" flashes for a second, then disappears. Through testing I found out this is because the message displays first for some reason, and only after does the scene change thus resetting the text.
I tried using coroutines to delay MessageValue from being altered until the scene changed:
public override void OnDisconnected(DisconnectCause cause) //Callback for when device fails to connect to server. Parameter 'cause' is the cause of this failure
{
StartCoroutine(GoToCSM());
DisplayErrorMessage();
}
IEnumerator GoToCSM()
{
Debug.Log("cor started");
SceneManager.LoadScene("Character Select Menu")
yield return new WaitForSeconds(3);
DisplayErrorMessage();
Debug.Log("Done");
}
public Text Message; //Initialises a 'Text' type object, which will be set to the Connection fail message
static string MessageValue = " "; //Initialises a string which will be written to the 'text' component of the above object
public void DisplayErrorMessage() //Method that displays a connection error message to the user
{
MessageValue = "AAAAAAA"; //Writes the string to be displayed to MessageValue
Message.text = MessageValue; //Sets the above text to the 'text' component of the Message object, thus displaying it on the screen
}
However the coroutine never goes past the yield statement. It just stops at the yield statement and doesn't continue (even the Debug.Log("Done") doesn't get logged).
But when I tried switching some things round and put SceneManager.LoadScene("Character Select Menu") beneath the yield statement, that was executed just fine, as well as the debug statement below. I have no idea why this could be, and am very confused.
This was meant to be an extremely simple 10 minute task and I've wasted days trying to figure out what to do now. Any help would be extremely greatly appreciated. Thank you!
When switching scenes the object running the coroutines gets destroyed. Which results in it never executing the delayed code in the coroutines, this also applies when loading the same scene as you have currently loaded.
Unity reloads the whole scene, it resets everything!
This is also the reason why you see the text flashing for a few seconds. You set the text of some component in your scene, then unity reloads it and its reset.
SceneManager.LoadScene is not instant it just tells unity to start loading the Scene and then switching to it when ready.
Which by the way is not a very performant thing to do and should only be done when you need to really reset it.
If you want to pass values such as cause of disconnection from one scene to another you should use static variables.
These are not stored in objects(that get deleted on scene load). They are static and get saved when switching scenes.
It would help if you shared some more details about the structure of your project. That can help us find a solution that suits your needs.

Scrape data from WebSocket with C# .Net

I need to scrape data from a websocket "just one time".
I mean that I don't need to get continuosly data from the source but I need
to get the data one time and exit from the elaboration.
I don't need Async task, I just need to use it like a simple API.
I'm struggling with web search but I didn't find any solution.
Thanks to support
I think your are struggling to find such code as websocket is almost a bi-directional protocol, not really for a RPC style.
But to answer your need, you could certainly use a library such as websocket-sharp . Your code to send a command text and receive back a return message would look like this :
using System;
using WebSocketSharp;
namespace Example
{
public class Program
{
public static void Main (string[] args)
{
using (var ws = new WebSocket ("ws://YOUR_URI_HERE")) {
ws.OnMessage += (sender, e) =>
Console.WriteLine ("It's ok I got my answer back : " + e.Data);
ws.Connect ();
ws.Send ("COMMAND FOR THE SERVER");
Console.ReadKey (true);
}
}
}
}
Hope that code will help you to get started.

Issue with loaded Midi.Net DLL

Lately I'm having some issues in different applications that I have made. All of these applications use a Midi-controller to send midi-notes to a lighting desk. The issue is the same for all of these applications.
In runtime, when I'm working on the application, it sometimes occurs that my complete application freezes. I don't get any warningmessages, nor is the debugger popping up to tell me what's wrong. It always occurs when I want to play a midi-note. The only thing I can do at that point, is to reboot the entire machine, which is not that funny.
Because the application hangs and I don't get any debugging information, I'm certain it has to do with the DLL I use to send Midi-notes and that there's an issue there or in the way I have implemented the dll.
I've posted the code below and I would appreciate it, if someone could tell me what I'm doing wrong?
This is de code in the mainform initializing the Midi
MidiTools midi;
private void initMidi()
{
midi = new MidiTools();
midi.Enabled = true;
}
The initMidi() is called from inside the Form_Load-function.
The code to play a Midi-note is:
midi.playNote(22,0)
Below is the code inside the MidiTools-class file
using Midi;
namespace MidiTest
{
class MidiTools
{
public bool Enabled { get; set; }
OutputDevice outputDevice = OutputDevice.InstalledDevices[1];
Channel selectedChannel = Channel.Channel16;
int velocity = 127;
private void playNote(int noteNumber, int delay)
{
// CONVERT THE NOTE
Note selectedNote = (Note)noteNumber;
if (Enabled)
{
Thread.Sleep(delay);
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss NOTE: ") + selectedNote.ToString());
outputDevice.Open();
outputDevice.SendNoteOn(selectedChannel, selectedNote, velocity);
outputDevice.Close();
}
}
}
}
The Midi-library itself was downloaded from this link:
https://midi-dot-net.googlecode.com/files/midi-dot-net_src_1.0.5.zip
In the past I've tried multiple ways of fixing this problem. I've tried inserting a bigger delay, I've tried cueing the messages in a list and processing them one by one to prevent a midinote from being asked to play wile another note is still being sent, but none of those helped.
In 98% of the cases it works, it's just occasionally that it freezes on me.
I'm using the M-Audio Midisport controller. (http://www.m-audio.com/products/view/midisport-4x4-anniversary-edition) but it has also happened on other controllers.
So any help is greatly appreciated.
Best regards,
Kenneth

Visual Studio delay between multiple startup projects?

how to add some delay between startup projects in solution?
I want Client project to be started after 2-3 seconds from starting WindowsService.
Why I need this?
WindowsService runs socket server and Client runs socket to connect to server. WindowsService loads slowly than Client, and this causes an exception on client side when connecting to server which is not run yet
I would probably add a retry mechanism within the client. That way not only does it help in the "starting up from Visual Studio" case - it also helps if the server happens to be restarting while the real client connects. The fact that the server is on a faster machine doesn't mean the server will never need to restart, does it?
Indeed, you may well want to add this retry mechanism in such a way that the client can recover even if the server is restarted while it's connected. It depends on what the project is doing, of course.
You can use Mutex locking to sync the two startup project.
Program 1 (StartUp Project 1):
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
class Program1
{
private static bool isNewMutexCreated = true;
private static Mutex mutex;
static void Main(string[] args)
{
mutex = new Mutex(true, "Global\\ConsoleApplication1", out isNewMutexCreated);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
Console.WriteLine("Application1 executed on " + DateTime.Now.ToString());
Console.ReadKey();
}
static void CurrentDomain_ProcessExit(Object sender, EventArgs e)
{
if (isNewMutexCreated)
{
Console.WriteLine("Mutex Released");
mutex.ReleaseMutex();
}
}
}
}
Program 2 (StartUp Project 2):
namespace ConsoleApplication2
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
class Program2
{
static void Main(string[] args)
{
Mutex mutex = null;
Thread.Sleep(5000);
while (mutex == null)
{
try
{
mutex = Mutex.OpenExisting("Global\\ConsoleApplication1");
}
catch (Exception)
{
Console.WriteLine("Mutex not found on " + DateTime.Now.ToString());
Thread.Sleep(3000);
}
}
Console.WriteLine("Application2 executed on " + DateTime.Now.ToString());
Console.ReadKey();
}
}
}
Another simpler option for testing is to just delay the client if the debugger is attached like this:
if (System.Diagnostics.Debugger.IsAttached)
{
System.Threading.Thread.Sleep(2000);
}
You might wrap that in an #if DEBUG block if you like. Anyway I think this should be the least amount of work :)
In case of multiple start-up projects, they are loaded in the order they are specified neither simultaneously nor randomly. http://msdn.microsoft.com/en-us/library/09138bex(v=vs.90).aspx
So ,may be if you specify "client" after "window service", then it may workout fine. And if you don't want to got the coded way suggested above, then (for testing only) you can manually attach the "client" process to you solution from a different solution after your desired delay.
http://msdn.microsoft.com/en-us/library/c6wf8e4z(v=vs.100).aspx
If the client needs to be started after, you need to adjust your list, as at the moment its started before!
I would also code a "/wait" which on loading app if it finds that flag, waits for it maybe useful in use too.
You can set the server project as the single startup project and use this macro to launch the server and the client with a delay:
Sub DebugServerAndClientWithDelay()
DTE.Debugger.Go(False)
System.Threading.Thread.Sleep(2000)
DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate()
DTE.ActiveWindow.Object.GetItem("SolutionName\ClientProjectName").Select(vsUISelectionType.vsUISelectionTypeSelect)
DTE.ExecuteCommand("ClassViewContextMenus.ClassViewProject.Debug.Startnewinstance")
End Sub
You can add a button to your toolbar or use a shortcut key to run this macro.
Just add a procedure to check whether the socket is open or not. If the socket is open continue executing your code and try checking again if the socket is not open. This way even if you start the windows service later there will be no problem.
For the n-tier application I am currently working on, I combined the Mutex method suggested by Romil (slightly different code but same principle) and encapsulated it within a method with a [Conditional("DEBUG")] attribute applied (so it gets stripped out in release mode). We also surround the mutex logic with if (System.Diagnostics.Debugger.IsAttached) {...} since QA builds use Debug mode.
We originally just used a Thread.Sleep with a wait period that worked for most developers machines, but we ran into problems because devs' computer speeds vary and as we added more and more to the server bootstrapper, we had to keep increasing the wait period.
Why don't you just pass an argument to the client application which sets the delay?
static void main(string[] args)
{
// Sleep some time
int delay;
if (args.Length > 0 && int.TryParse(args, out delay))
{
Thread.Sleep(delay);
}
// Initialize client
}
Now you can add the delay in milliseconds to the command-line arguments for the project startup.
I also agree that if possible, it's better to solve your problem structurally, so it doesn't matter when your client and server start.

Read Event Log From Newest to Oldest

I have written a short program to establish the uptime for remote PC's using the event log messages which are posted at startup and shutdown. Currently the logic is :
foreach (eventlogentry)
{
if (entryTime > OldestTime)
{
if (entry = Startup)
{
addOnTime(entry.Time);
}
if (entry = Shutdown)
{
addOffTime(entry.Time);
}
}
}
"OldestTime" define how far to scan backwards in time....
I would like to know if there is anyway to easily ammend my program to read the events from newest to oldest?
It's reading remote event logs and its taking a while for this function to run, as it starts at the end and reads forward.
I know this because I added a "else" block to the first "if" to break out of the foreach block, if the entry isnt within the timespan we are looking for and the program stop's at the first event it reads.
It has been a while since you asked this question, but i ran into the same problem and found a solution.
using System.Diagnostics;
using System.Linq;
EventLog events = new EventLog("Application", System.Environment.MachineName);
foreach (EventLogEntry entry in events.Entries.Cast<EventLogEntry>().Reverse())
{
//Do your tasks
}
This awnser still is not as fast as to just enumerate it forward but it is a bit more elegant than using a loop to copy items to a list.
#leinad13, for your application you need to change System.Environment.MachineName to a string with the name of the computer you want the events from and change "Application" to the log you want to see. I think "System" in your case.
Your best solution may be to move the data into a list and then reverse the order of that. Something like the following:
EventLog eventLog = new EventLog();
eventLog.Log = myEventLog;
var eventList = new List<EventLogEntry>();
foreach(EventLogEntry entry in eventLog.Entries)
{
eventList.Add(entry);
}
eventList.Reverse();
That should get the data in the reverse order, i.e. latest first, and then you can just process it as before but this time exit the loop when you hit a date before the oldest time.
Its not an ideal solution as you are still processing the whole log but it may be worth trying out to see if you get an improvement in performance

Categories

Resources