So I have this function, designed to download YouTube videos from the internet.
However whenever I run it, it does not catch any exception. Even an explicitly thrown new exception().
It's a WPF program so before anyone mentions bad coding etiquette, please don't. I'm more concerned with getting my program working at the moment.
Here's the code that creates the thread:
void button1_Click (object sender, RoutedEventArgs e)
{
this.IsEnabled = false;
this.downloadProgressText.Text = "Beginning....";
int selectedIndex = this.queueListView.SelectedIndex;
Thread newThread = new Thread (() => Download_Handler(classContainer, 0, selectedIndex, 0));
newThread.Start();
}
And the threaded function itself:
private void Download_Handler (ClassContainer classCont, int curVidPosition, int selectedIndex, int retryCount)
{
ObservableCollection<Video> finishedUrls = new ObservableCollection<Video> ();
ObservableCollection<Video> urlList = videoQueue.Items;
for (int position = curVidPosition, urlListCount = urlList.Count; position < urlListCount; position++)
{
try
{
downloadProgressText.Dispatcher.Invoke(new UpdateSelectedListItemCallback (this.UpdateSelectedListItem), new object[] {
position
});
Video vid = urlList [position];
if (classCont.DownloadingCode.DownloadVideo(vid, this, position) != null)
{
finishedUrls.Add(vid);
}
if (finishedUrls != null && finishedUrls.Count > 0)
{
classCont.IOHandlingCode.WriteUrlsToFile(finishedUrls, true);
}
}
catch (Exception ex)
{
var exceptionMessage = ex.Message;
if (retryCount <= 4)
{
downloadProgressText.Dispatcher.Invoke(new UpdateProgressBarCallback (this.UpdateProgressBar), new object[] {
string.Format(CultureInfo.InstalledUICulture, "URL {0}: {1}. Retrying.... ({2}/{3})", position + 1, classContainer.ConversionCode.Truncate(exceptionMessage, 50), retryCount.ToString(CultureInfo.CurrentCulture), "3"),
-1
});
Thread.Sleep(850);
Download_Handler(classCont, position, selectedIndex, retryCount + 1);
}
else
{
if (finishedUrls.Count < 10)
{
finishedUrls.Clear();
}
downloadProgressText.Dispatcher.Invoke(new UpdateProgressBarCallback (this.UpdateProgressBar), new object[] {
classCont.ConversionCode.Truncate(exceptionMessage, 100),
-1
});
}
}
}
videoQueue.Items = finishedUrls.Count > 0 ? (ObservableCollection<Video>)urlList.Where(video => finishedUrls.All(item => item != video)).Select(video => video) : urlList;
if (this.queueListView.Items.Count > 0)
{
this.RefreshQueue(videoQueue.Items, selectedIndex < this.queueListView.Items.Count ? 0 : selectedIndex);
}
this.IsEnabled = true;
}
This coding scheme worked just fine in WinForms (well, with slight differences), but since the move to WPF I just cannot figure it out!
EDIT:
Including additional code:
public Video DownloadVideo (Video video, MainWindow MainForm, int position)
{
MainForm.Dispatcher.Invoke(new MainWindow.UpdateProgressBarCallback (MainForm.UpdateProgressBar), new object[] {
0,
string.Format(CultureInfo.InstalledUICulture, "Beginning download from '{0}'", video.Location)
});
/*
* Get the available video formats.
* We'll work with them in the video and audio download examples.
*/
IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(video.Location, false);
if ((video.Format != VideoType.Mp4 && videoInfos.Any(info => (info.Resolution == video.Resolution && info.VideoType == video.Format)) || video.Format == VideoType.Mp4 && video.Resolution == 360))
{
VideoInfo currentVideo = videoInfos.First(info => info.VideoType == video.Format && info.Resolution == video.Resolution);
MainForm.Dispatcher.Invoke(new MainWindow.UpdateProgressBarCallback (MainForm.UpdateProgressBar), new object[] {
-1,
string.Format(CultureInfo.InstalledUICulture, "Downloading '{0}{1}' at {2}p resolution", Conversion.Truncate(currentVideo.Title, 56), currentVideo.VideoExtension, currentVideo.Resolution)
});
//DownloadAudio(videoInfos);
this.Download_Actual(videoInfos, MainForm, video.Resolution, position, video.Format);
return video;
}
if (videoInfos.Where(info => info.VideoType == video.Format).All(info => info.Resolution != video.Resolution) || (video.Format == VideoType.Mp4 && video.Resolution != 360))
{
List<int> resolutionsEstablished = new List<int> ();
List<VideoType> formatsEstablished = new List<VideoType> ();
using (StreamWriter outfile = new StreamWriter ("Acceptable Options.txt"))
{
outfile.Write(string.Format(CultureInfo.InstalledUICulture, "This file will show you all formats available for the current URL, as well as the resolutions that are acceptable for that URL.\n\n{0}:\n", video.Location));
foreach (VideoType format in videoInfos.Where(info => info.VideoType != VideoType.Unknown && formatsEstablished.All(format => info.VideoType != format)).Select(info => info.VideoType))
{
if (format == VideoType.Mp4)
{
outfile.Write(string.Format(CultureInfo.InstalledUICulture, "Format: {0} | Resolution: {1}p\n", format, "360"));
}
else
{
foreach (int resolution in videoInfos.Where(info => info.Resolution >= 144 && info.Resolution < 720 && resolutionsEstablished.All(res => info.Resolution != res) && info.VideoType == format).Select(info => info.Resolution))
{
outfile.Write(string.Format(CultureInfo.InstalledUICulture, "Format: {0} | Resolution: {1}p\n", format, resolution));
resolutionsEstablished.Add(resolution);
}
}
resolutionsEstablished.Clear();
formatsEstablished.Add(format);
}
}
throw new NotSupportedException("An acceptable options file has been exported to the program's root folder. Check there for more information.");
}
return null;
}
private void Download_Actual (IEnumerable<VideoInfo> videoInfos, MainWindow MainForm, int resolution, int position, VideoType format)
{
/*
* Select the first .mp4 video with 360p resolution
*/
VideoInfo video = videoInfos
.First(info => info.VideoType == format && info.Resolution == resolution);
/*
* If the video has a decrypted signature, decipher it
*/
if (video.RequiresDecryption)
{
DownloadUrlResolver.DecryptDownloadUrl(video);
}
/*
* Create the video downloader.
* The first argument is the video to download.
* The second argument is the path to save the video file.
*/
Settings settings = Storage.ReadFromRegistry();
var videoName = RemoveIllegalPathCharacters(video.Title) + video.VideoExtension;
var videoPath = Path.Combine(settings.TemporarySaveLocation, videoName);
var finalPath = Path.Combine(settings.MainSaveLocation, videoName);
if (!File.Exists(finalPath))
{
var videoDownloader = new VideoDownloader (video, videoPath);
// Register the ProgressChanged event and print the current progress
videoDownloader.DownloadProgressChanged += (
(sender, args) => MainForm.downloadProgressBar.Dispatcher.Invoke(new MainWindow.UpdateProgressBarCallback (MainForm.UpdateProgressBar), new object[] {
(int)args.ProgressPercentage,
null
})
);
/*
* Execute the video downloader.
* For GUI applications note, that this method runs synchronously.
*/
videoDownloader.Execute();
File.Move(videoPath, finalPath);
}
else
{
MainForm.downloadProgressText.Dispatcher.Invoke(new MainWindow.UpdateProgressBarCallback (MainForm.UpdateProgressBar), new object[] {
0,
null
});
throw new FieldAccessException("{0}({1}) already exists! Download process has been aborted and considered successful.");
}
}
I've stripped your code back to basics and works fine for me. Would probably need a complete code sample
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Thread newThread = new Thread(Download_Handler);
newThread.Start();
}
private void Download_Handler()
{
try
{
throw new Exception();
}
catch (Exception)
{
}
}
I figured it out. It was really stupid of a mistake....
So I call public delegate void UpdateProgressBarCallback (int progress, string message); to update text and progress bar values.
In this case, in the catch block, I was attempting to pass as the other way around, IE public delegate void UpdateProgressBarCallback (string message, int progress);. THAT'S why it was being weird. It all works now.
Related
I've made a small tool bar that sits in a transparent form, it loads a variable sized menu from a text file and can be changed on the fly. Each button is a type of Label, the bar is just a list of buttons and adds/removes them in the correct spots. Width of the form is only a little bigger than the menu bar so that sub menu isn't cut off
Everything is working sweet except, when I reload everything part of the toolbar is lost. I've attempted to change the width so many ways, I've cleared and removed the controls from the form, refreshing the form/menu, updating it etc however nothing seems to make it work as intended EXCEPT if I call the reload function twice in a row, it works. I can't see why calling it once doesn't work but calling it twice works.
I'm fine with calling reload twice in a row as it would only be called a couple times a week.
Question: what on earth is causing this?
photo of issues first photo shows what it should look like, second is after removing a menu button and reloading, third is after adding a button and reloading
//calling this.reload() doesn't work
//calling this.reload();this.reload() works
void reload(Object o = null, EventArgs e = null)
{
this._menuBar.clear();
this.loadFromFile();
}
void loadFromFile(Object o = null, EventArgs e = null)
{
try
{
if (File.Exists("kpi.txt"))
{
string cline = "", cmenu = "", lhs = "";
menuList mb = null;
StreamReader sr = new StreamReader("kpi.txt");
while (!sr.EndOfStream)
{
cline = sr.ReadLine(); //get current line
if (cline.Length > 0 && cline[0] != ';')
{
//check if main menu/command
if (cline[0] == '[')
{
cmenu = Regex.Match(cline, #"(?<=^\[)[a-zA-Z -\#_{-~\^\r\n]+(?=\])").Value;
if (cmenu != "")
{
mb = this._menuBar.addMenuButton(cmenu);
mb.data["options"] = Regex.Match(cline, #"\/\w+$").Value;
var match = Regex.Match(cline, #"(?<=<)([^>\[\]\r\n]+)(?=>)");
mb.data["count"] = (match.Success ? match.Value : "0");
mb.data["copy"] = "";
applyMenuOptions(mb, false);
}
}
//just a standard line
else
{
cline = cline.Trim();
lhs = Regex.Match(cline, #"^[^\;\<\[\]\r\n]+(?=$|\<|\;)").Value;
if (mb.getSubMenuItem(lhs) == null)
{
var newButton = mb.addSubMenu(lhs);
if (newButton != null)
{
newButton.parent = mb;
newButton.data["options"] = mb.data["options"];
newButton.data["copy"] = Regex.Match(cline, #"((?<=\;)[^\[\]\<\r\n]+(?=<|$))").Value;
var matches = Regex.Match(cline, #"(?<=<)([^>\[\]\r\n]+)(?=>)");
int intout = 0;
if (int.TryParse(matches.Value, out intout))
{//no description
newButton.data["description"] = "";
newButton.data["count"] = intout.ToString();
}
else
{
newButton.data["description"] = matches.Value;
newButton.data["count"] = (matches.NextMatch().Success ? matches.NextMatch().Value : "0");
}
applyMenuOptions(newButton);
newButton.addMiddleClick(this.addcopy);
if (newButton.data["options"].Contains("i"))
{
newButton.addRightClick(this.appendInfo);
newButton.addRightClick(this.increment);
}
}
}
}
}
}
sr.Close();
this._menuBar.squish();
this.Width = this._menuBar.Width+50;
}
else
{
menuList mb = this._menuBar.addMenuButton("menu");
mb.data["options"] = "\\m";
mb.data["count"] = "0";
mb.data["copy"] = "";
mb.data["description"] = "";
applyMenuOptions(mb, false);
saveDictonary();
}
}
catch (Exception ex)
{
MessageBox.Show("Failed to load data " + ex);
//ILog log = LogManager.GetLogger(typeof(Program));
//log.Info(ex);
}
}
public menuList addMenuButton(string s, int w = 0, int h = 0, int x = -1, int y = -1)
{
menuList mb = new menuList(this._form, s);
if (this.menuItems.Exists(z => z.Text == s)) return null;
mb.Width = (w==0?settings.intOf("ButtonWidth"):w);
mb.Height = (h==0?settings.IntOf("ButtonHeight"):h);
if (x == -1 || y == -1)
mb.Location = new Point(this.menuItems.Count > 0 ? this.menuItems.Last().Location.X + this.menuItems.Last().Width : padding);
else mb.Location = new Point(x, y);
mb.BringToFront();
mb.Show();
this.menuItems.Add(mb);
// this.Refresh();
return mb;
}
internal void clear()
{
foreach(var i in this.menuItems)
{
this._form.Controls.Remove(i);
i.clear();
i.Dispose();
}
this.menuItems.Clear();
this._form.Controls.Remove(this);
this.menuItems = new List<menuList>();
this._form.Controls.Add(this);
}
internal void squish()
{
try
{
this.Width = (this.menuItems.Count * this.menuItems.First().Width) + (2 * padding);
}
catch(Exception ex) { MessageBox.Show(""+ex); }
}
Found the culprit, bother the button class and the tool bar class were both adding themselves to the form control instead of button class adding to the tool bar (picture box) controls!
Removing transparency showed the buttons not moving when the tool bar was moved!
I was using Cefsharp Winforms, and recently I've been trying to switch to Offscreen. Everything works just fine, except now my code doesn't wait for EvaluateScriptAsync to complete before returns the page's source.
Or maybe I am just not quite understand how this task thing is working. Here is my progress so far:
private static void WebBrowserFrameLoadEnded(object sender, FrameLoadEndEventArgs e)
{
var browser = (CefSharp.OffScreen.ChromiumWebBrowser)sender;
if (e.Frame.IsMain)
{
browser.FrameLoadEnd -= WebBrowserFrameLoadEnded;
var x = browser.EvaluateScriptAsync("/* some javascript codes */");
if (x.IsCompleted && x.Result.Success)
{
x.ContinueWith(a =>
{
var task = browser.GetSourceAsync();
task.ContinueWith(d =>
{
if (d.IsCompleted)
{
globalRtnVal = d.Result;
}
}).ConfigureAwait(false);
});
}
}
}
And my main code is like this:
/* some codes */
CefSharp.OffScreen.ChromiumWebBrowser asd = new CefSharp.OffScreen.ChromiumWebBrowser(/* url */);
asd.BrowserSettings.Javascript = CefSharp.CefState.Enabled;
asd.BrowserSettings.WebSecurity = CefSharp.CefState.Disabled;
asd.FrameLoadEnd += WebBrowserFrameLoadEnded;
int tryCount = 0;
do
{
Thread.Sleep(3000);
RtnHtml = globalRtnVal;
if (String.IsNullOrEmpty(RtnHtml))
tryCount++;
if (tryCount == 10 && String.IsNullOrEmpty(RtnHtml))
{
/* some codes */
return null;
}
}
while (String.IsNullOrEmpty(RtnHtml));
/* some codes */
I have an ExampleSstreaming class which actually I got from GitHub of IBM Watson SDK (speech to text service demo). Here it is
public class ExampleStreaming : MonoBehaviour
{
private int m_RecordingRoutine = 0;
private string m_MicrophoneID = null;
private AudioClip m_Recording = null;
private int m_RecordingBufferSize = 5;
private int m_RecordingHZ = 22050;
private SpeechToText m_SpeechToText = new SpeechToText();
void Start()
{
LogSystem.InstallDefaultReactors();
Log.Debug("ExampleStreaming", "Start();");
Active = true;
Debug.Log("start");
StartRecording();
}
public void Update() {
Debug.Log(m_SpeechToText.IsListening);
}
public bool Active
{
get { return m_SpeechToText.IsListening; }
set
{
if (value && !m_SpeechToText.IsListening)
{
m_SpeechToText.DetectSilence = true;
m_SpeechToText.EnableWordConfidence = false;
m_SpeechToText.EnableTimestamps = false;
m_SpeechToText.SilenceThreshold = 0.03f;
m_SpeechToText.MaxAlternatives = 1;
m_SpeechToText.EnableContinousRecognition = true;
m_SpeechToText.EnableInterimResults = true;
m_SpeechToText.OnError = OnError;
m_SpeechToText.StartListening(OnRecognize);
}
else if (!value && m_SpeechToText.IsListening)
{
m_SpeechToText.StopListening();
}
}
}
private void StartRecording()
{
if (m_RecordingRoutine == 0)
{
Debug.Log("m_RecordingRoutine");
UnityObjectUtil.StartDestroyQueue();
m_RecordingRoutine = Runnable.Run(RecordingHandler());
}
}
private void StopRecording()
{
if (m_RecordingRoutine != 0)
{
Microphone.End(m_MicrophoneID);
Runnable.Stop(m_RecordingRoutine);
m_RecordingRoutine = 0;
}
}
private void OnError(string error)
{
Active = false;
Log.Debug("ExampleStreaming", "Error! {0}", error);
}
private IEnumerator RecordingHandler()
{
Log.Debug("ExampleStreaming", "devices: {0}", Microphone.devices);
m_MicrophoneID = Microphone.devices[0];
Debug.Log("m_MicrophoneID : " + m_MicrophoneID);
m_Recording = Microphone.Start(m_MicrophoneID, true, m_RecordingBufferSize, m_RecordingHZ);
yield return null; // let m_RecordingRoutine get set..
Debug.Log("m_Recording : " + m_Recording.length);
if (m_Recording == null)
{
Debug.Log("m_Recording is null");
StopRecording();
yield break;
}
bool bFirstBlock = true;
int midPoint = m_Recording.samples / 2;
float[] samples = null;
while (m_RecordingRoutine != 0 && m_Recording != null)
{
int writePos = Microphone.GetPosition(m_MicrophoneID);
if (writePos > m_Recording.samples || !Microphone.IsRecording(m_MicrophoneID))
{
Log.Error("MicrophoneWidget", "Microphone disconnected.");
StopRecording();
yield break;
}
if ((bFirstBlock && writePos >= midPoint)
|| (!bFirstBlock && writePos < midPoint))
{
// front block is recorded, make a RecordClip and pass it onto our callback.
samples = new float[midPoint];
m_Recording.GetData(samples, bFirstBlock ? 0 : midPoint);
AudioData record = new AudioData();
record.MaxLevel = Mathf.Max(samples);
record.Clip = AudioClip.Create("Recording", midPoint, m_Recording.channels, m_RecordingHZ, false);
record.Clip.SetData(samples, 0);
m_SpeechToText.OnListen(record);
bFirstBlock = !bFirstBlock;
}
else
{
// calculate the number of samples remaining until we ready for a block of audio,
// and wait that amount of time it will take to record.
int remaining = bFirstBlock ? (midPoint - writePos) : (m_Recording.samples - writePos);
float timeRemaining = (float)remaining / (float)m_RecordingHZ;
yield return new WaitForSeconds(timeRemaining);
}
}
yield break;
}
private void OnRecognize(SpeechRecognitionEvent result)
{
Debug.Log("OnRecognize");
if (result != null && result.results.Length > 0)
{
foreach (var res in result.results)
{
foreach (var alt in res.alternatives)
{
string text = alt.transcript;
Debug.Log(text);
Log.Debug("ExampleStreaming", string.Format("{0} ({1}, {2:0.00})\n", text, res.final ? "Final" : "Interim", alt.confidence));
}
}
}
}
}
and this is the line i add to get microphone. I just edit it to provide Microphone Device at zero index which was actually null (I don't know why, is this intentionally left or an error), in the function RecordingHandler .
m_MicrophoneID = Microphone.devices[0];
but unfortunately it is not showing any output log in EventOnRecognize which i think that it should execute.
Wile it displaying these logs, after some seconds (as i given length 5 of the audio). What i am doing wrong, i am unable to understand that how speech to text.
[DEBUG] OnListenClosed(), State = DISCONNECTED
[DEBUG] KeepAlive exited.
I have also tried IBM Watson Speech To text Scene it is also not showing anything.
I am not able to stream real-time output yet but become able to convert audio clip into text through watson service and here is the simple code (which took three days).
using UnityEngine;
using System.Collections;
using IBM.Watson.DeveloperCloud.Services.SpeechToText.v1;
public class AudioClipToTextWatson : MonoBehaviour {
// Non-streaming
SpeechToText m_SpeechToText = new SpeechToText();
public AudioClip m_AudioClip = new AudioClip();
public bool on = false;
void Start () {
m_AudioClip = Microphone.Start(Microphone.devices[0], false, 4, 44100);
m_SpeechToText.Recognize(m_AudioClip, OnRecognize);
// Streaming
m_SpeechToText.StartListening(OnRecognize);
// Stop listening
m_SpeechToText.StopListening();
}
private void OnRecognize(SpeechRecognitionEvent result)
{
Debug.Log("result : " + result);
if (result != null && result.results.Length > 0)
{
foreach (var res in result.results)
{
foreach (var alt in res.alternatives)
{
string text = alt.transcript;
Debug.Log(text);
Debug.Log(res.final);
}
}
}
}
}
Note :You can record and an audio clip using your microphone and convert it to text. If you already have an audio then drop it to inspector and comment out the first line in Start Event.
I solved Error
I encounter the same issue with Unity 2018.3.14f1.
I just change player settings and then works fine
file -> build settings - > player settings -> Other Settings
Configuration
Scripting runtime version : .Net 4x equivalent
API Compatibility level: .Net 4x
I'm reading continuously from a TcpClient streamreader.
The data coming from the stream is raw XML. There is no message framing. So there is now reliable method to know when the message is finished. Though I only have 3 XML messages coming from the server. But when they are coming is unknown. And I can't configure/program the server.
This is my code so far.
public void Start()
{
StreamReader reader = new StreamReader(_tcpClient.GetStream());
char[] chars = new char[Int16.MaxValue];
while (!_requestStop)
{
try
{
while ((reader.Read(chars, 0, chars.Length)) != 0)
{
string s = new string(chars);
s = removeEmptyChars(s);
if (s.IndexOf("<foo", StringComparison.OrdinalIgnoreCase) > 0 &&
s.IndexOf("</foo>", StringComparison.OrdinalIgnoreCase) > 0)
{
Console.WriteLine(s);
OnAlarmResponseComplete(new CustomEventArgs(s));
}
if (s.IndexOf("<bar", StringComparison.OrdinalIgnoreCase) > 0 &&
s.IndexOf("</bar>", StringComparison.OrdinalIgnoreCase) > 0)
{
Console.WriteLine(s);
OnAckComplete(new CustomEventArgs(s));
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//break;
}
}
reader.Close();
Console.WriteLine("Stopping TcpReader thread!");
}
Then in my main thread I'm processing the events. I'm adding them to a list.
Where I process the list.
When I'm debugging my application, I will be receiving 10 foo and 10 bar messages. And in my lists I have only 1 foo and 1 bar message stored.
Are the eventhandlers to slow to process this? Or am I missing something?
Here is the code you should use to cover all kinds of input issues (foo or bar received partially, foo and bar received together, etc..)
I can't say I approve using string parsing to handle XML content, but anyways.
private static string ProcessAndTrimFooBar(string s, out bool foundAny)
{
foundAny = false;
int fooStart = s.IndexOf("<foo", StringComparison.OrdinalIgnoreCase);
int fooEnd = s.IndexOf("</foo>", StringComparison.OrdinalIgnoreCase);
int barStart = s.IndexOf("<bar", StringComparison.OrdinalIgnoreCase);
int barEnd = s.IndexOf("</bar>", StringComparison.OrdinalIgnoreCase);
bool fooExists = fooStart >= 0 && fooEnd >= 0;
bool barExists = barStart >= 0 && barEnd >= 0;
if ((fooExists && !barExists) || (fooExists && barExists && fooStart < barStart))
{
string fooNodeContent = s.Substring(fooStart, fooEnd - fooStart + 6);
s = s.Substring(fooEnd + 6);
Console.WriteLine("Received <foo>: {0}", fooNodeContent);
OnAlarmResponseComplete(new CustomEventArgs(fooNodeContent));
foundAny = true;
}
if ((barExists && !fooExists) || (barExists && fooExists && barStart < fooStart))
{
string barNodeContent = s.Substring(barStart, barEnd - barStart + 6);
s = s.Substring(barEnd + 6);
Console.WriteLine("Received <bar>: {0}", barNodeContent);
OnAckComplete(new CustomEventArgs(barNodeContent));
foundAny = true;
}
return s;
}
public static void Start()
{
StreamReader reader = new StreamReader(_tcpClient.GetStream());
char[] chars = new char[Int16.MaxValue];
while (!_requestStop)
{
try
{
int currentOffset = 0;
while ((reader.Read(chars, currentOffset, chars.Length - currentOffset)) != 0)
{
string s = new string(chars).TrimEnd('\0');
bool foundAny;
do
{
s = ProcessAndTrimFooBar(s, out foundAny);
} while (foundAny);
chars = s.PadRight(Int16.MaxValue, '\0').ToCharArray();
currentOffset = s.Length;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//break;
}
}
reader.Close();
Console.WriteLine("Stopping TcpReader thread!");
}
I a have microchip mcp2200 device. To device is attached tree buttons (as digital inputs).
I use it as feedback machine.
I attached it to windows server 2003 x64. Then i used microchips mcp2200 driver and Managed SimpleIO DLL in my C# app.
In C# i use time with frequency 500 ms to check if button was pressed. After hour or two server has constant high cpu usage. If i kill C# program, all is ok. How can i lover cpu usage? Or my code has wrong?
Some code:
void timer1_Tick(object sender, EventArgs e)
{
if (DateTime.Now.ToString("HH") == _turnOffApp) Environment.Exit(0); //after working hours, turn off app. Task scheduler will start it at 8 AM
if (btn_down == 99)
{ //if button is UP
bool connStatus = SimpleIOClass.IsConnected();
if (connStatus)
{
lblConnStatus.Text = "Connected";
unsafe
{
uint rez1 = 2;
uint* rez = &rez1;
for (uint i = 0; i < 8; i++)
{
if (i == 5 || i == 7) continue; //unused pins
rez1 = 2;
if (SimpleIOClass.ReadPin(i, rez))
{
string rez11 = rez1.ToString();
this.Controls["label" + i.ToString()].Text = rez1.ToString();
if (rez1.ToString() == "0") // 0 = button down, 1 = button up
{
RegisterButton(i);
i = 8;
continue;
}
}
else
{
try { this.Controls["label" + i.ToString()].Text = "ReadPinErr"; }
catch { }
}
}
}
}
else
{
lblConnStatus.Text = "NOT Connected";
}
}//end btn_down == 99
}
void RegisterButton(uint poga)
{
btn_down = poga;
device = Device(poga);
CheckUserInput();
}
void SendBtnToServer(string btn)
{
try
{
string uri = #"http://web-server.lan/pogas.php?device="+ device+ "&p=" + btn;
WebClient clietn = new WebClient();
clietn.Headers.Add("Cache-Control", "no-cache");
clietn.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
clietn.DownloadString(uri);
clietn.Dispose();
}
catch (Exception ex) { try { File.AppendAllText(logFails, DateTime.Now.ToString() + " " + ex.ToString() + "\n\r"); } catch { } }
}
void CheckUserInput()
{
Thread.Sleep(2000); //wait 2 sec until user releases button
bool connStatus = SimpleIOClass.IsConnected();
if (connStatus)
{
lblConnStatus.Text = "Connected";
unsafe
{
uint rez1 = 2;
uint* rez = &rez1;
string ctrName = "label" + btn_down.ToString();
if (SimpleIOClass.ReadPin(btn_down, rez))
{
if (rez1.ToString() == "1") // poga atlaista
{
// register button press
if (btn_down == Pogas["smaids"]) { OSD(":)"); new Thread(() => SendBtnToServer("1")).Start(); }
if (btn_down == Pogas["neitrals"]) { OSD(":|"); new Thread(() => SendBtnToServer("2")).Start(); }
if (btn_down == Pogas["bedigs"]) { OSD(":("); new Thread(() => SendBtnToServer("3")).Start(); }
if (btn_down == Pogas["smaids2"]) { OSD(":)"); new Thread(() => SendBtnToServer("1")).Start(); }
if (btn_down == Pogas["neitrals2"]) { OSD(":|"); new Thread(() => SendBtnToServer("2")).Start(); }
if (btn_down == Pogas["bedigs2"]) { OSD(":("); new Thread(() => SendBtnToServer("3")).Start(); }
}
}
else this.Controls[ctrName].Invoke(new Action(() => this.Controls[ctrName].Text = "Read pin ERROR (Release)"));
}
}
else
{
lblConnStatus.Text = "NOT Connected";
}
btn_down = 99;
}// CheckUserInput
Answer is: C# app is restarted every hour via Scheduled job. No more high cpu usage.