So im attempting to create a auto typer. And the problem is if i spam the message, And click the application to stop the spam it just freezes up. I as then told i need to use Threads. So i had a read around and this is what i came up with:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace tf2trade
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public bool started = true;
private void spam()
{
string test = text1.Text;
Thread.Sleep(2000);
while (started == false)
{
foreach (char c in test)
{
SendKeys.Send(c.ToString());
}
SendKeys.Send("{ENTER}");
}
}
Thread test = new Thread(spam);
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void submit_Click(object sender, EventArgs e)
{
if (started == true)
{
started = false;
submit.Text = "Stop";
submit.Refresh();
spam();
}
else
{
started = true;
submit.Text = "Start";
}
}
}
}
Now this code gives me the error:
A field initializer cannot reference the non-static field, method, or property 'tf2trade.Form1.spam()'
What did i do wrong? :(
Thanks in advance,
Alana.
Honestly I wouldn't waste your time troubleshooting this error. Instead, consider using one of the existing approaches to writing multi-threaded applications in .NET . The technology you use will depend on the type of problem you are trying to solve. For short/quick tasks consider using:
thread pool
.net task library
If you are creating a "long" running task you could create 1 or more native threads, but I wouldn't recommend doing this until you have a better understanding of what you are doing. There are a lot of pitfalls. For example, A lot of developers think more threads equals better performance... this is not true.
REFERENCES
thread pool:
http://msdn.microsoft.com/en-us/library/system.threading.threadpool(v=vs.110).aspx
tasks: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx
native thread: http://msdn.microsoft.com/en-us/library/system.threading.thread(v=vs.110).aspx
Related
im trying to do a program that read a string from a website e send it to another. the process to read string for the first works correctly, and also the function to send a string to the other works, but have problem when this function was called from the timer..
here is part of my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using CefSharp.WinForms.Internals;
namespace CodePinger
{
public partial class Form1 : Form
{
public bool login = true;
private static System.Timers.Timer TimerCheck;
public Form1()
{
InitializeComponent();
TimerCheck = new System.Timers.Timer(5000);
TimerCheck.Elapsed += new ElapsedEventHandler(CheckEvent);
TimerCheck.AutoReset = true;
CheckForIllegalCrossThreadCalls = false;
webBrowser1.ScriptErrorsSuppressed = true;
chromiumWebBrowser1.Load("https://firstwebsite.com");
webBrowser1.Navigate("http://secondwebsite.com");
}
private async void CheckEvent(Object source, ElapsedEventArgs e)
{
if (login) {
string script = "document.getElementById('SecondSDISP').innerText;";
JavascriptResponse jr = chromiumWebBrowser1.EvaluateScriptAsync(script).Result;
if (jr.Success)
{
if (jr.Result.ToString().Contains("01"))
{
label2.ForeColor = Color.Red;
label2.Text = jr.Result.ToString();
sendCode(jr.Result.ToString());
}
}
else
{
label2.ForeColor = Color.Black;
label2.Text = "no data";
}
label4.Text = timer.ToString();
}
}
private void button2_Click(object sender, EventArgs e)
{
TimerCheck.Enabled = true;
TimerCheck.Start();
button2.Enabled = false;
}
public void sendCode(string code)
{
string msg = "";
if (code == "1") msg = "1 coda";
else msg = code.ToString() + " code";
var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
textarea.InnerHtml = msg;
textarea.Focus();
var allsvg = webBrowser1.Document.GetElementsByTagName("svg");
foreach (HtmlElement svg in allsvg)
{
if (svg.GetAttribute("className").Contains("-send"))
{
svg.InvokeMember("click");
break;
}
}
}
private void button4_Click(object sender, EventArgs e)
{
sendCode("1");
}
}
}
also after i started the timer, if i click to button4 to test the function, it works correctly. instead of when its called from timer
the error is:
System.InvalidCastException
HResult=0x80004002
Message=Specified cast is not valid.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.UnsafeNativeMethods.IHTMLDocument2.GetLocation()
at System.Windows.Forms.WebBrowser.get_Document()
at CodePinger.Form1.sendCode(String code) in C:\Users\Flynns82\source\repos\CodePinger\Form1.cs:line 105
at CodePinger.Form1.<CheckEvent>d__9.MoveNext() in C:\Users\Flynns82\source\repos\CodePinger\Form1.cs:line 63
the indicated line are:
105) var textarea = webBrowser1.Document.GetElementsByTagName("textarea")[0];
63) sendCode(jr.Result.ToString());
can someone explain me what is the problem?
Most likely your problem is you are trying to access the WebBrowser from a non-STA thread (aka the 'UI Thread')
When you use the button4_click handler your code is running on the STA Thread (by default), however, when a Time Event handler is called back it happens in a different thread (which is not the STA one) thus you will have problems invoking/accessing properties on ActiveX/Components (who reside in the STA thread) if you do not "invoke" back into the STA.
I recommend to take a look to the following SO Question: STA vs MTA for a technical explanation.
For solving the invoke problem look into the following SO Question: Automating the InvokeRequired code pattern
On the other hand the browser exposes a NavigateComplete event, you do not need to have a time checking when the page is loaded, just hook yourself to the event and wait for it after navigate, the DOM will be stable once this event fires.
I use a GD4430 handheld scanner from the company Datalogic with the included OPOS driver. With the following code I manage to address the scanner. When I start the program, the scanner becomes active and you can scan. But I can not display the results in a TextBox.
Does anyone see where the error lies?
Visual Studio 2010 C#
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;
namespace TestRead
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
axOPOSScanner1.BeginInit();
axOPOSScanner1.Open("USBHHScanner");
axOPOSScanner1.ClaimDevice(0);
axOPOSScanner1.DeviceEnabled = true;
axOPOSScanner1.DataEventEnabled = true;
axOPOSScanner1.PowerNotify = 1; //(OPOS_PN_ENABLED);
axOPOSScanner1.DecodeData = true;
}
void axOPOSScanner1_DataEvent(object sender, AxOposScanner_CCO._IOPOSScannerEvents_DataEventEvent e)
{
textBox1.Text = axOPOSScanner1.ScanDataLabel;
textBox2.Text = axOPOSScanner1.ScanData.ToString();
axOPOSScanner1.DataEventEnabled = true;
axOPOSScanner1.DataEventEnabled = true;
}
}
}
Was not the processing of AxOPOSScanner1.BeginInit() on the source originally in Form1.Designer.cs instead of here?
(I am assuming that the source file name is Form1.cs)
As below(in Form1.Designer.cs):
this.axOPOSScanner1 = new AxOposScanner_CCO.AxOPOSScanner();
((System.ComponentModel.ISupportInitialize)(this.axOPOSScanner1)).BeginInit();
this.SuspendLayout();
There is a possibility that the problem has occurred because you moved it to Form1.cs or calling BiginInit() on both Form1.Designer.cs and Form1.cs.
Or, the following processing does not exist in Form1.Designer.cs, or there is a possibility that the specified function name(axOPOSScanner1_DataEvent) is wrong.
this.axOPOSScanner1.DataEvent += new AxOposScanner_CCO._IOPOSScannerEvents_DataEventEventHandler(this.axOPOSScanner1_DataEvent);
In addition:
What you should do is to temporarily store the return value of all the methods, add a process to determine whether the method was executed normally, likewise It is to read the ResultCode property immediately after setting the property(possibly causing an error) and add processing to judge whether the property setting was done normally.
Also, although not related to DataEvent, PowerNotify setting must be done before DeviceEnabled = true.
Continuing from my previous question: Trying to show a Windows Form using a DLL that is imported at the runtime in a console application
The form I am showing using the code given in the answer to my previous question by #Ksv3n is freezing (showing a wait cursor over it). For code please check out above link.
Try to use a BackgroundWorker, like this:
(I dind't compiled the code, this is an example for the approach)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace DLLTest
{
class Program
{
static void Main(string[] args)
{
BackgroundWorker m_oWorker;
m_oWorker = new BackgroundWorker();
m_oWorker.DoWork += new DoWorkEventHandler(m_oWorker_DoWork);
m_oWorker.RunWorkerAsync();
Console.ReadLine();
}
static void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
{
string DLLPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\TestLib.dll";
var DLL = Assembly.LoadFile(DLLPath);
foreach (Type type in DLL.GetExportedTypes())
{
dynamic c = Activator.CreateInstance(type);
c.test();
}
}
}
}
Online Resource:Background Worker for Beginners
With the below code, I've tested it out and the loading of the form works fine standalone, but when the program goes to check if a file exists, the form doesn't load properly and I'm at a loss as to what to do. Is there another method of checking to see if a file exists that I could use in this instance?
EDIT I've made a new 'startup' form to run the file exists check, but it still doesn't work. Again the form loads, but the contents of the form don't and the form itself freezes.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
using System.IO;
using System.Collections;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Diagnostics;
using System.Windows.Input;
namespace program1
{
public partial class Startup : Form
{
public Startup()
{
InitializeComponent();
}
private void Startup_Load(object sender, EventArgs e)
{
notifyIcons norm = new notifyIcons();
Settings set = new Settings();
set.Show();
string curFile = Environment.CurrentDirectory + "\\age.txt";
if (File.Exists(curFile))
{
norm.Show();
this.Close();
}
else
{
set.Show();
for (;;)
{
if (File.Exists(curFile)) norm.Show(); this.Close();
Application.DoEvents();
}
}
}
}
}
I have no idea what this code is supposed to do.. but I can tell you why its not working.
while (ageFileExists)
That is never false. Therefore, your loop will continually loop... forever. You need to set it false somehow in the loop. I have no idea what sort of rules govern that though.
The reason the form doesn't load is because the loop never exits.. and so the message loop that makes the window do anything can never continue processing window messages.
If you can give more context around what you're trying to do I could help you with a proper solution. As it stands though, I can only see the problem.
while(ageFileExists)
{
if (File.Exists(curFile)) ageFileExists = true;
set.WindowState = FormWindowState.Normal;
}
If that file exists you have an infinite loop. You never set ageFileExists to false and that loop does nothing at all. And where does that label go? I seriously doubt you need to be using goto. Your code doesn't make much sense as it stands.
By using the following code in the main form, it seemed to work a treat! I think the critical part was Application.DoEvents();
Thanks for all of your assistance
InitializeComponent();
set.Show();
set.WindowState = FormWindowState.Minimized;
string curFile = Environment.CurrentDirectory + "\\age.txt";
if (File.Exists(curFile)) goto Labelx;
set.WindowState = FormWindowState.Normal;
for (; ; ) { Application.DoEvents(); if (File.Exists(curFile)) break; }
set.WindowState = FormWindowState.Minimized;
Labelx:TextReader reader = File.OpenText(Environment.CurrentDirectory + "\\age.txt");
I am building an application with C# using WPF, the application needs to continually subscribe to an event that is generated by a third party server, and update the UI controls based on the received events,Initially I need to connect to the server before events can be issued out, the connection is an expensive operation so I put that one on a seperate thread and I used the WPF Dispatcher BeginInVoke and a delegate method to subscribe to the events, now the problem is this will work fine for sometime after I run the application, I mean the UI controls will be notified for some time before it stops recieving notification, I tried put stop point and stepped into the code, the method being called by the delegate is not being invoked by the dispatcher and the third party server is continuoslly issuing the events but my dispatcher doesnot pick it up again, I have tried all possible method, but I couldnot find any solution to it, anybody with help and solutions will be appreciated
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Text.RegularExpressions;
using System.Windows.Threading;
using System.Media;
using ClientPhone.Utility;
using System.Threading.Tasks;
using ClientPhone.Core.DAL;
using ClientPhone.Core.Model;
namespace ClientPhone.View
{
/// <summary>
/// Interaction logic for TestView.xaml
/// </summary>
public partial class TestView : Window
{
private FreeSwitchEventHandler _freeSwitchEventHandler;
private delegate void EventDelegate(switch_event evt);
public static NotificationInfo _notificationInfo;
private EventDelegate del;
public TestView()
{
InitializeComponent();
del = new EventDelegate(actual_event_handler);
ConnectToServer();
}
private void ConnectToServer()
{
string err = string.Empty ;
const uint flags = (uint)(switch_core_flag_enum_t.SCF_USE_SQL | switch_core_flag_enum_t.SCF_USE_AUTO_NAT);
freeswitch.switch_core_set_globals();/*Next 3 lines only needed if you want to bind to the initial event or xml config search loops */
freeswitch.switch_core_init(flags, switch_bool_t.SWITCH_FALSE, ref err);
IDisposable search_bind = FreeSWITCH.SwitchXmlSearchBinding.Bind(xml_search, switch_xml_section_enum_t.SWITCH_XML_SECTION_CONFIG);
event_bind = FreeSWITCH.EventBinding.Bind("SampleClient", switch_event_types_t.SWITCH_EVENT_ALL, null, event_handler, true);
}
private void event_handler(FreeSWITCH.EventBinding.EventBindingArgs args)
{
Dispatcher.BeginInvoke(del, DispatcherPriority.Send,new object[] { args.EventObj });
}
private void actual_event_handler(switch_event evt)
{
_eventInfo = _eventHandler.HandleEvents(evt);
if (_eventInfo != null && _eventInfo.Callee == _userId)
{
if ((!_callState.IsCallIncoming && _eventInfo.State!="hangup")&& _eventInfo.Caller!=null)
{
SetIsAnsweredParameters()
}
}
if (_eventInfo != null && (_eventInfo.ChannelState == "CS_DESTROY" || _eventInfo.ChannelState == "CS_HANGUP"))
{
ResetUIState();
}
}
private void SetIsAnsweredParameters()
{
if (!_isTimercounting)
{
_timerMinutes = 0;
_timerSeconds = 0;
_callState.IsCallActive = true;
_isTimercounting = true;
_soundManager.StopPlayer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Start();
grdNotification.Visibility = Visibility.Visible;
}
}
private void UpdateHistory(string call)
{
lstHistory.Items.Add(call);
}
}
}
The listener is probably throwing an exception. You won't know about it because I suspect you're not calling EndInvoke to rejoin the exception onto the main thread.
Change your code to this:
Action action = () => ... ;
action.BeginInvoke(action.EndInvoke, null);
When the service fails now, you'll get the exception on the main thread, and can work out what's causing it by viewing the stack trace.
Edit
This shouldn't be necessary as you are actually using Dispatcher.BeginInvoke which runs on the UI thread anyway.
I suggest adding some logging, and also try debugging in Visual Studio with first chance exceptions enabled.
var op = Dispatcher.BeginInvoke(del, DispatcherPriority.Send,
new object[] { args.EventObj });
op.Completed += (s,e) => logger.Debug("Completed");
op.Aborted += (s,e) => logger.Debug("Aborted");
One possibility is that the FreeSwitch module is actually passing your handler to unmanaged code. In that case, the GC wouldn't know that the delegate is actually reachable and would collect it. You can test this theory by creating a member field to store the event_handler delegate:
_newEventDelegateMember = new ProperDelegateType(event_handler);
event_bind = FreeSWITCH.EventBinding.Bind("SampleClient",
switch_event_types_t.SWITCH_EVENT_ALL, null,
**_newEventDelegateMember**, true);