C# subscribe to event from another Task.Factory - c#

could please help with that. I can not subscribe for event fired by an object from another Task.
Note: If i took the code outside the Task, it works fine. you can see the commented code
private void Form1_Load(object sender, EventArgs e)
{
_machines.Add(new Machine() { Ip = "192.168.1.10", Name = "Machine_01", Status = "Connected" });
dgvMachines.DataSource = _machines;
}
private void startLiveMonitoringToolStripMenuItem_Click(object sender, EventArgs e)
{
//if (_machines.Count <= 0) return;
//_fpMachine = new ZktFingerPrint(_machines[0].Ip, _machines[0].Name);
//_fpMachine.Connect();
//_fpMachine.EnableLiveFingerPrintDetection();
//_fpMachine.NewFingerPrintDetected += FpMachine_NewFingerPrintDetected;
foreach (var machine in _machines)
{
Task.Factory.StartNew(() =>
{
IFingerPrintMachine fpMachine = new ZktFingerPrint(machine.Ip, machine.Name);
fpMachine.Connect();
fpMachine.EnableLiveFingerPrintDetection();
fpMachine.NewFingerPrintDetected += FpMachine_NewFingerPrintDetected;
});
}
}
private void FpMachine_NewFingerPrintDetected(object sender, FingerPrintEventArgs e)
{
var fpr = new FingerPrintRecord(e.FingerPrintDateTime, e.UserId);
dgvMonitor.Rows.Add("Machine_01", fpr.FingerPrintDateTime, fpr.UserSn);
}

Related

second windows requires STA

So I am using AI, to transcribe some text in azure, I am copying the text into background chipboard (That I found here), I am retrieving the text and sending it to a second windows
The problem is that Windows gives me this issue
System.InvalidOperationException: 'The calling thread must be STA, because many UI components require this.'
this is the code that is breaking things
private void SpeechRecognizer_SessionStopped(object? sender, SessionEventArgs e)
{
var sb = new StringBuilder();
foreach (var item in Words)
{
sb.Append(item);
}
BackgroundClipboard.SetText(sb.ToString());
if (!string.IsNullOrEmpty(BackgroundClipboard.GetText()))
{
var spellWindow = new SpellCheckWindow();
spellWindow.Show();
}
}
private void SpeechRecognizer_SessionStarted(object? sender, SessionEventArgs e)
{
}
private void SpeechRecognizer_Recognized(object? sender, SpeechRecognitionEventArgs e)
{
if (e.Result.Reason == ResultReason.RecognizedSpeech)
{
foreach (var item in e.Result.Text)
{
Words.Add(item);
}
}
}
private void SpeechRecognizer_Recognizing(object? sender, SpeechRecognitionEventArgs e)
{
}
}
Try create/show the window via the main dispatcher like this
Application.Current.Dispatcher.Invoke(() => {
var spellWindow = new SpellCheckWindow();
spellWindow.Show();
});

C# Windows Forms Serial Communication with GMap app crash

I've written desktop application, that receives location via serial communication from NRF/GPS module, split that data in order to distinguish latitude, longitude and then i load these coordinates to map(i use GMap). But when i receive data, first 1 or 2 seconds it comes in a little confused form(like this 06840.370056;49.84006068). And i thought adding some Thread.Sleep will solve this problem, but instead application crashes after 5-10 seconds. How can i solve this problem, because i want my app run smoothly? Here is part of my code:
public partial class Form1 : Form
{
public string dataIn;
private List<PointLatLng> _points;
public Form1()
{
_points = new List<PointLatLng>();
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GMapProviders.GoogleMap.ApiKey = AppConfig.Key;
string[] ports = SerialPort.GetPortNames();
cBoxCom.Items.AddRange(ports);
btnConnect.Enabled = true;
btnDisconnect.Enabled = false;
gMap.MapProvider = GMapProviders.GoogleMap;
gMap.ShowCenter = false;
gMap.DragButton = MouseButtons.Left;
gMap.SetPositionByKeywords("Chennai, India");
}
private void btnConnect_Click(object sender, EventArgs e)
{
serialPort1.PortName = cBoxCom.Text;
serialPort1.BaudRate = Convert.ToInt32(cBoxBaudrate.Text);
btnConnect.Enabled = false;
btnDisconnect.Enabled = true;
serialPort1.Open();
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
btnConnect.Enabled = true;
btnDisconnect.Enabled = false;
}
}
private void btnClearDataIn_Click(object sender, EventArgs e)
{
if (richBoxReciever.Text != "")
{
richBoxReciever.Text = " ";
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
dataIn = serialPort1.ReadExisting();
this.Invoke(new EventHandler(ShowData));
}
private void ShowData(object sender, EventArgs e)
{
Thread.Sleep(3000);
richBoxReciever.Text += dataIn;
Thread.Sleep(5000);
string[] locationData = dataIn.Split(new char[] { ';' });
List<string> tokens = new List<string>();
foreach (string s in locationData)
{
if (s.Length != 0)
{
tokens.Add(s);
}
}
txtLat.Text = tokens[0];
txtLon.Text = tokens[1];
}

CefSharp use DevToolsClient execute Method after, call Wait() function Waiting, Lead to program card to death?

CefSharp Version: 86.0.241.0
.Net Framework 4.5.2
I am new to C# and my English is not good. Sorry....
Try a variety of methods to implement:
private void button18_Click(object sender, EventArgs e)
{
//1
DevToolsClient devTool = chromiumWebBrowser1.GetBrowser().GetDevToolsClient();
devTool.ExecuteDevToolsMethodAsync("Browser.getVersion").Wait();// stuck
//2
DevToolsClient dev = DevToolsExtensions.GetDevToolsClient(chromiumWebBrowser1);
dev.ExecuteDevToolsMethodAsync("Browser.getVersion").Wait();// stuck
}
// load complete after:
chromiumWebBrowser1.FrameLoadEnd += new EventHandler<FrameLoadEndEventArgs>(new Action<object, FrameLoadEndEventArgs>((s, ea) => {
IBrowser browser = chromiumWebBrowser1.GetBrowser();
DevToolsClient devTool = chromiumWebBrowser1.GetBrowser().GetDevToolsClient();
//devTool.Browser.GetVersionAsync().Wait(); //execute nomal
devTool.DOM.GetDocumentAsync().Wait(); // stuck
}));
//
private void button1_Click(object sender, EventArgs e)
{
DevToolsClient devTool = chromiumWebBrowser1.GetBrowser().GetDevToolsClient();
//devTool.Page.ReloadAsync(); //nomal page reload
devTool.Page.ReloadAsync().Wait(); // stuck
}
In addition to being successful Browser.GetVersionAsync() in FrameLoadEnd event .
A solution has been found! use async/await solve.
private async void button1_Click(object sender, EventArgs e)
{
DevToolsClient devTool = chromiumWebBrowser1.GetBrowser().GetDevToolsClient();
DevToolsMethodResponse resp = await devTool.ExecuteDevToolsMethodAsync("DOM.getDocument");
Console.WriteLine(resp.ResponseAsJsonString);
}
The final solution:
//global variable
DevToolsClient devTool = null;
//Should be obtained at initialization time DevToolsClient,And only get it once
//Each call to GetDevToolsClient() messageId resets
chromiumWebBrowser1.IsBrowserInitializedChanged += new EventHandler(delegate {
devTool = chromiumWebBrowser1.GetBrowser().GetDevToolsClient();
});
//Common execution method method: CDP method name ,param: method param
public async Task<string> ExecuteDevToolsMethods(string method, IDictionary<string, object> param = null)
{
DevToolsMethodResponse resp = await devTool.ExecuteDevToolsMethodAsync(method, param);
return resp.ResponseAsJsonString;
}
//call
private void button3_Click(object sender, EventArgs e)
{
ExecuteDevToolsMethods("DOM.getDocument").ContinueWith(new Action<Task<string>>((result) => {
Console.WriteLine(result.Result);
}));
}
if Please point out if I have misunderstood,very thank!

How to stop browser navigating in csharp for windowsphone

I want to stop browser navigating,when i click button.I tried in the below method but it doesn't worked.
private void webBrowser1_Navigating(object sender, NavigatingEventArgs e)
{
button2.Click += new RoutedEventHandler((object caller,System.Windows.RoutedEventArgs f) =>
{
e.Cancel = true;
});
}
Try this one-
private void webBrowser_Navigating(object sender, NavigatingEventArgs e)
{
stop.IsEnabled=true;
stop.Click += new RoutedEventHandler((object caller, System.Windows.RoutedEventArgs f) =>
{
stopPressed = true;
});
if (stopPressed == true)
e.Cancel = true;
}
If you want to stop the browser navigating you can try like this:
private void stop_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
MiniBrowser.InvokeScript("eval", "document.execCommand('Stop');");
}

How to wait two BackgrandWorker's RunWorkerCompleted event finished?

That's the code:
private void button1_Click(object sender, EventArgs e)
{
ParaClass pcs = new ParaClass();
pcs.strPath = textBox1.Text;
pcs.sendedGrid = ugSrc;
this.backgroundWorker1.RunWorkerAsync(pcs);
ParaClass pcsB = new ParaClass();
pcsB.strPath = textBox2.Text;
pcsB.sendedGrid = ultraGrid2;
this.backgroundWorker2.RunWorkerAsync(pcsB);
doSomething();
}
and in both backgrandworker1 & backgrandworker2 ' complet event ,i write code like this:
private void backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
doSomethingelsebk1();
}
private void backgroundWorker2_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
doSomethingelsebk2();
}
now the problem is : the function doSomething() in button1's click event must wait both backgrandworker's complete event finish.
if i change doSomething() to
private void backgroundWorker2_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
doSomethingelsebk2();
doSomething();
}
then,because there are two thread,i don't know which thread will finish first,so what is the solution
Create 2 flags which represent complete state of 2 BackgroundWorker.
Turn each flag on in the RunWorkerCompleted event, then call doSomething() method.
In doSomething method, check if both flags is on, then continue to do, otherwise, return.
Create 2 AutoResetEvents, set them when each Background worker finishes and wait for them all in the main method with a WaitHandle.
WaitHandle[] handles = new WaitHandle[] { new AutoResetEvent(false), new AutoResetEvent(false)};
private void button1_Click(object sender, EventArgs e)
{
ParaClass pcs = new ParaClass();
pcs.strPath = textBox1.Text;
pcs.sendedGrid = ugSrc;
this.backgroundWorker1.RunWorkerAsync(pcs);
ParaClass pcsB = new ParaClass();
pcsB.strPath = textBox2.Text;
pcsB.sendedGrid = ultraGrid2;
this.backgroundWorker2.RunWorkerAsync(pcsB);
WaitHandle.WaitAll(this.handles);
doSomething();
}
private void backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
doSomethingelsebk1();
((AutoResetEvent)this.handles[0]).Set();
}
private void backgroundWorker2_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
doSomethingelsebk2();
((AutoResetEvent)this.handles[1]).Set();
}

Categories

Resources