Read through most (all?) of the answered questions regarding the C# BackgroundWorker but none seemed to apply to this situation. If I missed one, please point me in that direction!
Anyway, I having troubles getting the Ping process to run as a background process. I made a simple form application to send pings and report back. That worked fine but it would only results results to the user after the pings were complete -- thus the need to a background process. I am somewhat new to C# and was unfamiliar with the particulars of BackgroundWorker. However found a helpful walkthrough from Microsoft here: http://msdn.microsoft.com/en-us/library/ywkkz4s1.aspx
I am now attempting to get the same process to apply to a System.Net.NetworkInformation object instead of a System.IO.StreamReader object. I think I am really close (read: I can get the app to build and run) but I consistently get an error at runtime (see below).
This is the Microsoft code for their sample app. It works like a champ:
The method in MainForm.cs that calls the Words.cs class referenced in the walkthrough
void backgroundWorker1DoWork(object sender, DoWorkEventArgs e)
{
System.ComponentModel.BackgroundWorker worker;
worker = (System.ComponentModel.BackgroundWorker)sender;
Words WC = (Words)e.Argument;
WC.CountWords(worker, e);
}
The relevant method in the 'Words.cs' class
public void CountWords(
System.ComponentModel.BackgroundWorker worker,
System.ComponentModel.DoWorkEventArgs e)
{
// Initialize the variables.
CurrentState state = new CurrentState();
string line = "";
int elapsedTime = 20;
DateTime lastReportDateTime = DateTime.Now;
if (CompareString == null ||
CompareString == System.String.Empty)
{
throw new Exception("CompareString not specified.");
}
// Open a new stream.
using (System.IO.StreamReader myStream = new System.IO.StreamReader(SourceFile))
{
// Process lines while there are lines remaining in the file.
while (!myStream.EndOfStream)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
line = myStream.ReadLine();
WordCount += CountInString(line, CompareString);
LinesCounted += 1;
// Raise an event so the form can monitor progress.
int compare = DateTime.Compare(
DateTime.Now, lastReportDateTime.AddMilliseconds(elapsedTime));
if (compare > 0)
{
state.LinesCounted = LinesCounted;
state.WordsMatched = WordCount;
worker.ReportProgress(0, state);
lastReportDateTime = DateTime.Now;
}
}
// Uncomment for testing.
System.Threading.Thread.Sleep(5);
}
// Report the final count values.
state.LinesCounted = LinesCounted;
state.WordsMatched = WordCount;
worker.ReportProgress(0, state);
}
}
When I try a similar process (sending a Ping instead of a reading a file) I get this error:
Error: Object reference not set to an instance of an object.
Details: System.Collections.ListDictionaryInternal //This is defined in the MyApp namespace as: using System.Collections
Source: MyApp
StackTrack: at MyApp.MainForm.Bw01DoWork(Object sender, DoWorkEventArgs e) in
[path]\MainForm.cs:line 152
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
Target: Void Bw01DoWork(System.Object, System.ComponentModel.DoWorkEventArgs)
Here is my method. Line 152 referenced in the error is the very last line of the last method in MainForm.cs (the var names are different, but you get the idea):
void Bw01DoWork(object sender, DoWorkEventArgs e)
{
System.ComponentModel.BackgroundWorker worker;
worker = (System.ComponentModel.BackgroundWorker)sender;
PTResults PR = (PTResults)e.Argument;
PR.SendPings(worker, e); // Line 152
}
And the relevant portion of the PTResults.cs class:
using (Ping newPing = new Ping())
{
PingReply reply = newPing.Send([Target Site],[Timeout]);
if(reply.Status == IPStatus.Success)
{
state.PingOK = true;
}
else if(reply.Status == IPStatus.TimedOut)
{
state.PingOK = false;
state.PingUpdateState = " Timed Out";
}
else if(reply.Status != IPStatus.Success)
{
state.PingOK = false;
state.PingUpdateState = " FAILED";
}
else
{
state.PingOK = false;
state.PingUpdateState = " UNKNOWN";
}
worker.ReportProgress(0, state.PingOK);
}
I am thinking the System.Net.NetworkInformation.Ping component cannot be invoked the same way System.IO.StreamReader is. Thoughts?
I doubt it makes a difference but FWIW I am coding in SharpDevelop on a Windows 8.1 system.
Take a look at the Ping SendAsync, you may be able to eliminate most of your code - just call PingAsync, and handle the result being sure to dispatch it to the UI thread and then re-queue another call.
http://msdn.microsoft.com/en-us/library/ms144961(v=vs.110).aspx
Related
I have a few functions in a Solidworks Addin which call on a VBA macro (Via the runMacro2 method) a co-worker has been working on for the last few weeks. In his code he calls a Solidworks function which, under certain, unknown conditions, hangs for a long period of time. How long seems to depend upon the size and quantity of bodies in the part. Considering at least one of the functions we want to run this from i automatic, this just wont do.
I have tried using the Thread.Join(int) method (shown below) but it doesnt work. I also tried modifying the code from this answer Close a MessageBox after several seconds with the same results. Is there anything I can do either in C# or VBA to handle a timeout for this without re-writing his entire macro?
public void runBB()
{
Stopwatch testStop = new Stopwatch();
Thread workerThread = new Thread(bbRun);
testStop.Start();
workerThread.Start();
if (!workerThread.Join(50))
{
workerThread.Abort();
testStop.Stop();
MessageBox.Show("Unable to generate Bounding Box after " + testStop.ElapsedMilliseconds/1000 + " seconds. Please enter data manually.", "Solidworks Derped Error.");
}
return;
}//Still uses Macro (2-5-16)
public static void bbRun()
{
iSwApp.RunMacro2(macroPath + "BOUNDING_BOX.swp", "test11", "main", 0, out runMacroError);
return;
}
I was getting this same exact issue with SOLIDWORKS hanging on an open of a file. Almost all reference on SO was that you should never do this, but in this scenario, you either have to close it or wait forever. In C# I created a callWithTimeout method:
private void callWithTimeout(Action action, int timeoutMilliseconds, String errorText) {
Thread threadToKill = null;
Action wrappedAction = () =>
{
threadToKill = Thread.CurrentThread;
action();
};
IAsyncResult result = wrappedAction.BeginInvoke(null, null);
if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds)) {
wrappedAction.EndInvoke(result);
} else {
threadToKill.Abort();
throw new TimeoutException(errorText);
}
}
Then the code that was hanging put in a block as such:
bool timedOut = false;
try {
callWithTimeout(delegate() {
// code that hangs here
}, 60000, "Operation timed out. SOLIDWORKS could not open the file. This file will be processed later.");
} catch (TimeoutException){
timedOut = true;
} finally {
if(timedOut) {
Process[] prs = Process.GetProcesses();
foreach (Process p in prs) {
if (p?.ProcessName.Equals("SLDWORKS") ?? false)
p?.Kill();
}
}
}
In the constructor i'm calling WatchDirectory method:
private void WatchDirectory()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = userVideosDirectory;
watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
watcher.Filter = "*.mp4";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
}
Then the event OnChanged:
private void OnChanged(object source, FileSystemEventArgs e)
{
try
{
var info = new FileInfo(e.FullPath);
fileforupload = info.FullName;
if (e.ChangeType == WatcherChangeTypes.Changed)
{
var theSize = info.Length;
label2.BeginInvoke((Action)(() =>
{
label2.Text = theSize.ToString();
}));
}
dirchanged = true;
}
catch (Exception ee)
{
string err = ee.ToString();
}
}
Then i'm using a while loop to check when dirchange flag is true:
WatchDirectory();
while (dirchanged == false)
{
if (dirchanged == true)
{
Youtube_Uploader youtubeupload = new
Youtube_Uploader(fileforupload);
break;
}
}
The problem is that sometimes it's never changes the dirchanged to true on the OnChanged event. Not sure why. It seems to fire the OnChanged event but sometimes it doesn't execute the dirchanged = true;
Therefore inside the while loop dirchanged flag remains false all the time.
I added now a new method i called it IsFileLocked:
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
And i use this in the event OnChanged:
private void OnChanged(object source, FileSystemEventArgs e)
{
try
{
var info = new FileInfo(e.FullPath);
fileforupload = info.FullName;
IsFileLocked(info);
if (e.ChangeType == WatcherChangeTypes.Changed)
{
var theSize = info.Length;
label2.BeginInvoke((Action)(() =>
{
label2.Text = theSize.ToString();
}));
}
dirchanged = true;
}
catch (Exception ee)
{
string err = ee.ToString();
}
}
And in the method IsFileLocked i'm getting exception:
The process cannot access the file 'C:\Users\bout0_000\Videos\My Great Game - My Great Capture - 2015-08-10 14-22-52.mp4' because it is being used by another process.
I'm using external program that create the file and since the program still working on creating the file the watcher can't get to it.
So i have a confilct here from one side i want to know to watch when the file is ready finished created but on the other side i can't know since the external program still working on it.
So how can i find out when the external program finished working on the file and the file is ready ?
This is the whole part of the code of the while:
if (request.QueryString[0] == "stop")
{
dirchanged = false;
StartRecrod();
result = "Recording stopped and preparing the file to be shared on youtube";
WatchDirectory();
while (dirchanged == false)
{
if (dirchanged == true)
{
string ttttt = "ok";
break;
}
}
}
I added a string ttttt just for testing.
Sometimes it's getting to the string ttttt when using a break point and sometimes not.
In my program when i touch my android screen it send command to the pc web server and it's getting here but someting is wrong with the while loop and the flag dirchanged sometimes it does enter the while and the IF and does the string ttttt and sometimes it dosen't.
This is what i did now with the await:
TaskCompletionSource<bool> sy;
public async void SendResponse(HttpListenerRequest request)
{
string result = "";
string key = request.QueryString.GetKey(0);
if (key == "cmd")
{
if (request.QueryString[0] == "nothing")
{
return "Connection Success";
}
if (request.QueryString[0] == "start")
{
StartRecrod();
result = "Recording started";
}
if (request.QueryString[0] == "stop")
{
dirchanged = false;
StartRecrod();
result = "Recording stopped and preparing the file to be shared on youtube";
sy = new TaskCompletionSource<bool>();
WatchDirectory();
await sy.Task;
Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);
}
}
else
{
result = "Nothing have been done";
}
if (Youtube_Uploader.fileuploadedsuccess != null && Youtube_Uploader.fileuploadedsuccess != "")
{
result = Youtube_Uploader.fileuploadedsuccess;
}
return result;
}
But some problems.
First i'm getting errors over all the returns.
Error 2 Since 'Automatic_Record.Form1.SendResponse(System.Net.HttpListenerRequest)' returns void, a return keyword must not be followed by an object expression
And error when init my web server:
WebServer ws = new WebServer(SendResponse, "http://+:8098/");
On the SendResponse i'm getting:
Error 1 'void Automatic_Record.Form1.SendResponse(System.Net.HttpListenerRequest)' has the wrong return type
This errors happen now when changed the method to async.
This is my WebServer method that i get error when init it since it should get something else then async:
public WebServer(Func<HttpListenerRequest, string> method, params string[] prefixes)
: this(prefixes, method) { }
public void Run()
{
ThreadPool.QueueUserWorkItem((o) =>
{
Console.WriteLine("Webserver running...");
try
{
while (_listener.IsListening)
{
ThreadPool.QueueUserWorkItem((c) =>
{
var ctx = c as HttpListenerContext;
try
{
string rstr = _responderMethod(ctx.Request);
System.Diagnostics.Trace.Write(ctx.Request.QueryString);
//ctx.Request.QueryString
byte[] buf = Encoding.UTF8.GetBytes(rstr);
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder();
}
catch { } // suppress any exceptions
finally
{
// always close the stream
ctx.Response.OutputStream.Close();
}
}, _listener.GetContext());
}
}
catch { } // suppress any exceptions
});
}
This code is horribly broken. Yes, dirchanged is always false inside the while loop, because if it becomes true you won't be in the while loop any longer.
In addition, your code blocks events from occurring, which may block the file watcher event itself, and also is not optimization safe. Use proper synchronization, here's an example:
TaskCompletionSource<bool> sy;
private void OnChanged(object source, FileSystemEventArgs e)
{
sy.SetResult(true);
}
and wait with
sy = new TaskCompletionSource<bool>();
WatchDirectory();
await sy.Task; // or sy.Task.Wait()
(You'll need to use the async keyword on the method containing that code).
This fixes all the problems you had before -- it doesn't burn CPU cycles, it continues processing Windows messages, and it won't break if the compiler chooses to cache variables in registers.
dirchanged could be getting set to true just after evaluating the inner if block. Then, next loop it breaks out without ever running your uploader.
So you have two main questions?
1.) Why is dirchanged not being set to true?
and the apparent cause...
2.) How do you use FileSystemWatcher to only act on a file that's available for edit?
FileSystemWatcher is known for being a little touchy, and I agree with your diagnosis that file access is probably the culprit. An unpredictable file access error is exactly what I would expected from a FileSystemWatcher trying to do something with a file that was just modified. Can you edit the code that's creating the file? If so, one method I've used with FileSystemWatcher is to have it only watch for file creation of a fictitious file type such as ".fsw". The program creating the file will then rename it to ".fsw" whenever it is done editing it, that way the FileSystemWatcher only gets called when it has a file available to act upon, and it can then rename the file to it's actual type. Also, if you can edit the creation code, make sure that you are doing everything you can to release the file from there. I've seen this behavior before because I forgot to close a TextWriter.
Also, I would move the line
dirchanged = true;
Outside of the try statement. Why have it in there since it definitely wont throw an error? Also, your catch statement isn't really doing error handling. Any error in your try statement and you get ejected before reaching the dirchanged = true line without being alerted that this is what happened. Have you tested your delegate code on its own? Is there a need to have the if statement for type = changed right there? If you're troubleshooting, I would consider limiting your try statement content or moving it to after the while loop as much as possible.
Also, wouldn't this be a lot more simple for your while statement?
while (dirchanged == false){}
Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);
It's not the most elegant solution, but one work around is to simply wait if you know the program creating/editing the file is going to close it very soon...
while (dirchanged == false){}
System.Threading.Thread.Sleep(1000);
Youtube_Uploader youtubeupload = new Youtube_Uploader(fileforupload);
EDIT: Better yet, rather than a while statement use Ben Voigt's suggestion of a TaskCompletionSource. You'll still have to deal with the file being locked but you should be able to do that after the "task" has been flagged as completed.
I'm trying to use C# to control a command line application background, which can be downloaded here: http://www.ti.com/litv/zip/spmc015b
This is an app for motor voltage control, when I enter the app, like "b.exe -c 1", the console seems a kind of blocking model. Every command in this app begins with "#" symbol. See pics here:
http://i46.tinypic.com/zx5edv.jpg
What I'm trying to do is, use StandardInput.WriteLine("stat vout"); to measure the voltage. This will send a "stat vout" command to the console background and ideally return a voltage value. In this pic, it return some help hints. Duing all this time, it still in the blocking mode.
I want to get the return message with StandardOutput.ReadLine(); but failed. If ReadToEnd() then my program is freezed because this app never return to standard console, which is blocking.
When I tried BeginOutputReadLine(); OutputDataReceived event can truly obtain the message return from the console, like in the pics of "stat [vout|vbus|fault". But it limited in my single thread program.
My current situation is that, I use System.Timers.Timers in WinForms and every second will send a "stat vout2" command to read the voltage, and hopefully get the return value.
However, the System.Timers.Timers is asynchronous, so when I called BeginOutputReadLine() in this Timers thread, it prompted "An async read operation has already been started on the stream." In the meantime, as I've demonstrated above, I cannot use synchronous methods like ReadLine() to get the value.
So what should I do now? I truly need to run this command line app in multi-threading mode.
Thanks so much and wish everybody has a nice weekend.
--UPDATE on Apr 28 19:18 CST
Here is the relevant source code:
One of the WinFroms button will Start() the SystemClock Class, then Timing.Measuring() is executed every second. The TimingController Class will call GetVoltage() and GetCurrent() at the same time during one second according to the SystemClock, to measure the voltage and current.
In the Measuring Class, StandardInput.WriteLine("stat vout2"); to get the voltage from the console app, and StandardInput.WriteLine("stat cur"); to get the current. Both of them use BeginOutputReadLine() to get result since StandardOutput didn't work.
I use a isOutputObtained flag to indicating if data returned. Every time the reading is finished, I did call CancelOutputRead(); to cancel asynchronous read.
But it still give me the error exception of "An asynchronous read operation is already in progress on the StandardOutput stream"
public class SystemClock
{
TimingController Timing = new TimingController();
private Timer TimerSystemClock;
public SystemClock()
{
TimerSystemClock = new Timer();
TimerSystemClock.Interval = 1000;
TimerSystemClock.AutoReset = true;
TimerSystemClock.Elapsed += new ElapsedEventHandler(TimerSystemClock_Elapsed);
TimerSystemClock.Enabled = false;
Timing.ClockInstance = this;
}
public void Start()
{
TimerSystemClock.Enabled = true;
}
void TimerSystemClock_Elapsed(object sender, ElapsedEventArgs e)
{
Timing.Measuring();
}
}
public class TimingController
{
// Get singleton of Measurement Class
Measurement Measure = Measurement.GetInstance();
public SystemClock ClockInstance
{
get { return Clock; }
set { Clock = value; }
}
private void Measuring()
{
CurrentVoltage = Measure.GetVoltage();
CurrentCurrent = Measure.GetCurrent();
}
}
public sealed class Measurement
{
// Singleton
public static readonly Measurement instance = new Measurement();
public static Measurement GetInstance()
{
return instance;
}
private Process ProcMeasuring = new Process();
double measureValue
bool isOutputObtained;
private Measurement()
{
ProcMeasuring.StartInfo.FileName = "b.exe";
ProcMeasuring.StartInfo.Arguments = "-c 1";
ProcMeasuring.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
ProcMeasuring.StartInfo.UseShellExecute = false;
ProcMeasuring.StartInfo.RedirectStandardInput = true;
ProcMeasuring.StartInfo.RedirectStandardOutput = true;
ProcMeasuring.StartInfo.RedirectStandardError = true;
ProcMeasuring.StartInfo.CreateNoWindow = true;
ProcMeasuring.OutputDataReceived += new DataReceivedEventHandler(MeasurementOutputHandler);
}
public double GetVoltage(Machine machine)
{
isOutputObtained = false;
ProcMeasuring.StandardInput.WriteLine("stat vout2");
ProcMeasuring.BeginOutputReadLine();
while (!isOutputObtained)
{
isOutputObtained = true;
}
return measureValue;
}
public double GetCurrent(Machine machine)
{
isOutputObtained = false;
ProcMeasuring.StandardInput.WriteLine("stat cur");
ProcMeasuring.BeginOutputReadLine();
while (!isOutputObtained)
{
isOutputObtained = true;
}
return measureValue;
}
private void MeasurementOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data) && (outLine.Data != "# "))
{
measureCurrentValue = Convert.ToDouble(outLine.Data);
isOutputObtained = true;
ProcMeasuring.CancelOutputRead();
}
}
}
I think you have two options.
If it is ok to miss a sample because the previous one took too long, then set a flag to indicate that you are already sampling.
public class TimingController
{
// Get singleton of Measurement Class
Measurement Measure = Measurement.GetInstance();
bool isMeasuring = false;
public SystemClock ClockInstance
{
get { return Clock; }
set { Clock = value; }
}
private void Measuring()
{
if(isMeasuring) return;
isMeasuring = true;
CurrentVoltage = Measure.GetVoltage();
CurrentCurrent = Measure.GetCurrent();
isMeasuring = false;
}
}
If it is not ok to miss an interval, you could try creating a new process object for each call rather than reusing the existing process. This could create a lot of children though if the commands take a long time to complete.
Windows mobile 5; compact framework and relative newbie to c# and threads.
I want to download large files (several meg) from my own website; being GPRS this could take a while. I want to show a progress bar, and allow an option to cancel the download.
I've got a class called FileDownload and create an instance of it; give it a url and save location then:
MyFileDownLoader.Changed += new FileDownLoader.ChangedEventHandler(InvokeProgressBar);
BGDownload = new Thread(new ThreadStart(MyFileDownLoader.DownloadFile));
BGDownload.Start();
So I create an event handler for updates to progress bar and start the thread. This works fine.
I've got a cancel button which reads:
MyFileDownLoader.Changed -= InvokeProgressBar;
MyFileDownLoader.Cancel();
BGDownload.Join();
lblPercentage.Text = CurPercentage + " Cancelled"; // CurPercentage is a string
lblPercentage.Refresh();
btnUpdate.Enabled = true;
In the FileDownload class the key parts are:
public void Cancel()
{
CancelRequest = true;
}
In method Download file:
...
success = false;
try {
//loop until no data is returned
while ((bytesRead = responseStream.Read(buffer, 0, maxRead)) > 0)
{
_totalBytesRead += bytesRead;
BytesChanged(_totalBytesRead);
fileStream.Write(buffer, 0, bytesRead);
if (CancelRequest)
break;
}
if (!CancelRequest)
success = true;
}
catch
{
success = false;
// other error handling code
}
finally
{
if (null != responseStream)
responseStream.Close();
if (null != response)
response.Close();
if (null != fileStream)
fileStream.Close();
}
// if part of the file was written and the transfer failed, delete the partial file
if (!success && File.Exists(destination))
File.Delete(destination);
The code i'm using for the download is based on http://spitzkoff.com/craig/?p=24
The problem i've got is when I cancel, the download stops immediately, however it can take up to 5 seconds or so for the join process to complete. This is evidenced by lblPercentage.Text being updated after the join.
If I then try and download again, sometimes it works and sometimes I get a nullreference exception (still trying to track that down).
I think i'm doing something wrong in my approach to cancelling the thread.
Am i ?
public void Cancel()
{
CancelRequest = true;
}
I suppose you should add thread-safe to this action.
public void Cancel()
{
lock (this)
{
CancelRequest = true;
}
}
Hope this help!
I have an autodetect thread that tries to open the ports in order and match the received data, thus detecting the port where the relevant device sends the data. Now, there are some ports where the SerialPort.Open simply hangs the thread for ~30 secs. How can I set a timeout on the SerialPort.Open function?
From MSDN
Only one open connection can exist per SerialPort object.
The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly.
When you call Close(), this worker thread needs time to spin down and exit. The amount of time needed is not specified and you can't verify that it was done. All you can do is wait at least one second before you call Open() again.
I encountered the same problem and I hope my solution can help you.
You can detect the Serial Ports in a separate thread, which will be aborted in 500 ms.
// the Serial Port detection routine
private void testSerialPort(object obj)
{
if (! (obj is string) )
return;
string spName = obj as string;
SerialPort sp = new SerialPort(spName);
try
{
sp.Open();
}
catch (Exception)
{
// users don't want to experience this
return;
}
if (sp.IsOpen)
{
if ( You can recieve the data you neeed)
{
isSerialPortValid = true;
}
}
sp.Close();
}
// validity of serial port
private bool isSerialPortValid;
// the callback function of button checks the serial ports
private void btCheck(object sender, RoutedEventArgs e)
{
foreach (string s in SerialPort.GetPortNames())
{
isSpValid = false;
Thread t = new Thread(new ParameterizedThreadStart(testSerialPort));
t.Start(s);
Thread.Sleep(500); // wait and trink a tee for 500 ms
t.Abort();
// check wether the port was successfully opened
if (isSpValid)
{
textBlock1.Text = "Serial Port " + s + " is OK !";
}
else
{
textBlock1.Text = "Serial Port " + s + " retards !";
}
}
}
}
Possible improvements could be added into the solution. You can use multi-Thread to accelerate the process and use ProgressBar to display the progress clearly.
Add this in your code:
commPort = new SerialPort();
commPort.ReadTimeout = 1000000;
commPort.WriteTimeout = 1000000;
And I suggest you to see SerialPort.Open Method
If I understood you correctly, you wish to read data from the serial port even after timeout occurred.
If so, then you should catch the TimeoutException and continue your loop. e.g. MSDN CODE
public static void Read()
{
while (_continue)
{
try
{
string message = _serialPort.ReadLine();
Console.WriteLine(message);
}
catch (TimeoutException) { }
}
}