Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
When I execute this code in command line, it's working fine:
class Program
{
private static List<Ping> pingers = new List<Ping>();
private static List<string> value = new List<string>();
private static int instances = 0;
private static object #lock = new object();
private static int result = 0;
private static int timeOut = 2500;
private static int ttl = 7;
public static void Main()
{
string baseIP = "192.168.1.";
Console.WriteLine("Pinging destinations of D-class in {0}*", baseIP);
CreatePingers(254);
PingOptions po = new PingOptions(ttl, true);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] data = enc.GetBytes("");
SpinWait wait = new SpinWait();
int cnt =1;
Stopwatch watch = Stopwatch.StartNew();
foreach (Ping p in pingers)
{
lock (#lock)
{
instances += 1;
}
p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeOut, data, po);
cnt += 1;
}
//while (instances > 0)
//{
// wait.SpinOnce();
//}
watch.Stop();
for (int i = 0; i < value.Count; i++)
{
Console.WriteLine(value[i]);
}
DestroyPingers();
Console.WriteLine("Finished in {0}. Found {1} active IP-addresses.", watch.Elapsed.ToString(), result);
Console.ReadKey();
}
public static void Ping_completed(object s, PingCompletedEventArgs e)
{
lock (#lock)
{
instances -= 1;
}
if (e.Reply.Status == IPStatus.Success)
{
string sa = string.Concat("Active IP: ", e.Reply.Address.ToString());
value.Add(sa);
//Console.WriteLine(sa);
String diachiip = e.Reply.Address.ToString();
result += 1;
}
else
{
//Console.WriteLine(String.Concat("Non-active IP: ", e.Reply.Address.ToString()))
}
}
private static void CreatePingers(int cnt)
{
for (int i = 1; i <= cnt; i++)
{
Ping p = new Ping();
p.PingCompleted += Ping_completed;
pingers.Add(p);
}
}
private static void DestroyPingers()
{
foreach (Ping p in pingers)
{
p.PingCompleted -= Ping_completed;
p.Dispose();
}
pingers.Clear();
}
}
But when I convert from it to window form, it doesn't work. I don't kwow why, I have tried many different ways...
Code is here:
public partial class Form1 : Form
{
public static List<Ping> pingers = new List<Ping>();
public static List<string> value = new List<string>();
public static int instances = 0;
public static object #lock = new object();
public static int result = 0;
public int timeout = 2500;
public static int ttl = 7;
public Form1()
{
InitializeComponent();
}
public void btnscan_Click(object sender, EventArgs e)
{
string baseIP = "192.168.1.";
//int kt = Int32.Parse(txtkt.Text);
//int start = Int32.Parse(txtstart.Text);
CreatePingers(254);
PingOptions po = new PingOptions(ttl, true);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] data = enc.GetBytes("");
int cnt = 1;
Stopwatch watch = Stopwatch.StartNew();
foreach (Ping p in pingers)
{
lock (#lock)
{
instances += 1;
}
p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeout, data, po);
cnt += 1;
}
watch.Stop();
//Result alway return 0
lst1.Items.Add(result.ToString());
lst1.Items.Add(value.Count.ToString());
for (int i = 0; i < value.Count; i++)
{
lst1.Items.Add(value[i]);
lst1.Items.Add("\n");
}
DestroyPingers();
string a = "Finished in " + watch.Elapsed.ToString() + ". Found " + result + " active IP-addresses.";
lst1.Items.Add(a);
}
public static void CreatePingers(int kt)
{
for (int start = 1; start <= kt; start++)
{
// class System.Net.NetworkInformation.Ping
Ping p = new Ping();
p.PingCompleted += Ping_completed();
pingers.Add(p);
}
}
public static PingCompletedEventHandler Ping_completed()
{
PingCompletedEventHandler a = new PingCompletedEventHandler(abc);
return a;
}
static void abc(object s, PingCompletedEventArgs e)
{
value.Add("abc");
lock (#lock)
{
instances -= 1;
}
if (e.Reply.Status == IPStatus.Success)
{
string abcd = string.Concat("Active IP: ", e.Reply.Address.ToString());
value.Add(abcd);
result += 1;
}
}
public static void DestroyPingers()
{
foreach (Ping p in pingers)
{
p.PingCompleted -= Ping_completed();
p.Dispose();
}
pingers.Clear();
}
}
What is wrong in this code?
Method SendAsync returns 0 because you are not waiting for it to complete. You are missing await and async (see msdn):
async void btnscan_Click(object sender, EventArgs e)
{
...
await p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeout, data,
...
}
SpinWait was making code to work in console application. In winforms you should not use SpinWait (nor Sleep) in UI thread. You can create another thread (e.g. by using Task) and then you can copy/paste code from console application 1-to-1. But then you will need to use Invoke each time when you want to access UI controls.
async/await is really better.. if it will work (I concluded that from method name, I've no idea what method does, nor how to use it).
Perhaps I miss one thing, if SendAsync returns value, then you can get it by (the requirement to mark method where you use await with async still):
var result = await p.SendAsync(...);
Related
For a while now, i have been trying to make my RFID reader to automatically read (scan) a card. Although the former code i had, makes the reader scan the card when a button is pressed. But i want to be able to scan cards automatically and continuously, once any card is placed in the field. Here is what i tried. but i was not able to display the scanned UID in a textbox. Please, your help will be appreciated.
class CardReader : IDisposable
{
IntPtr _pSnr = Marshal.AllocHGlobal(1024);
private Thread _t;
private Action<string> _callback;
private volatile bool _stop;
public void ReadCard()
{
short icdev = 0x0000;
int status;
byte type = (byte)'A';//mifare one type is A
byte mode = 0x26; // Request the card which is not halted.
ushort TagType = 0;
byte bcnt = 0x04;//mifare hold on 4
IntPtr pSnr;
byte len = 255;
sbyte size = 0;
pSnr = Marshal.AllocHGlobal(1024);
for (int i = 0; i < 2; i++)
{
status = rf_request(icdev, mode, ref TagType);//request card
if (status != 0)
continue;
status = rf_anticoll(icdev, bcnt, pSnr, ref len);//i did anticol--get the card sn
if (status != 0)
continue;
status = rf_select(icdev, pSnr, len, ref size);//select one card
if (status != 0)
continue;
byte[] szBytes = new byte[len];
for (int j = 0; j < len; j++)
{
szBytes[j] = Marshal.ReadByte(pSnr, j);
}
String m_cardNo = String.Empty;
for (int q = 0; q < len; q++)
{
m_cardNo += byteHEX(szBytes[q]);
}
_callback(m_cardNo);
// txtSearchPurse.Text = m_cardNo;
break;
}
}
public void Work()
{
while (!_stop)
{
ReadCard();
Thread.Sleep(1000);
}
}
public void Start(Action<string> cardRead)
{
if (_t != null)
return;
_stop = false;
_callback = cardRead;
_t = new Thread(Work);
_t.Start();
}
public void Stop()
{
if (_t != null)
{
_stop = true;
_t.Join();
_t = null;
}
}
public void Dispose()
{
Marshal.FreeHGlobal(_pSnr);
}
}
And i tried to use it like this:
private void btnRequest_Click(object sender, EventArgs e)
{
var reader = new CardReader();
reader.Start(CardReaded);
}
private void CardReaded(string cardnr){
//txtSearchPurse.Text = _callback;
}
Here is what i tried. but i was not able to display the scanned UID in a textbox.
So your callback successfully fired? What error, if any, did you get? I'm guessing you got a "cross thread exception". If so, fix it like this:
private void CardReaded(string cardnr)
{
this.Invoke((MethodInvoker)delegate
{
txtSearchPurse.Text = cardnr;
});
}
I have a probably simple question about the task factory. I have to following code:
In this task is a loop that is polling data from the RS232 and a counter that stops polling after 10 times. After this "doCollect" will be set to false.
And now comes the strange thing: The task runs repeatedly. The caller code is:
// class Main()
RS232DataAquisition _RS232DataAquisition = new RS232DataAquisition();
public override void Run()
{
System.Diagnostics.Stopwatch timeout = new System.Diagnostics.Stopwatch();
timeout.Start();
_RS232DataAquisition.Start();
while ((timeout.ElapsedMilliseconds <= (dataGatherTime_inSeconds * 1000)) && _RS232DataAquisition.DoCollect)
{
System.Threading.Thread.Sleep(100);
}
timeout.Stop();
_RS232DataAquisition.Stop();
}
Per my understanding the Run() function should start the thread and return into the while-loop waiting for the thread to finish. But it never does?!
Here's the code for ReadDataFromRS232:
// sealed class RS232DataAquisition
private bool doCollect = false;
public bool DoCollect
{
get { return doCollect; }
}
public void Start()
{
doCollect = true;
currentTask = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
this.ReadDataFromRS232();
});
}
private void ReadDataFromRS232(int NumtoRead = 10)
{
var port = new System.IO.Ports.SerialPort(PortName);
int waitCount = 5;
var portExists = System.IO.Ports.SerialPort.GetPortNames().Any(x => x == PortName);
if (!portExists)
{
throw new ArgumentException("Port does not exist!");
}
while (port.IsOpen && waitCount-- > 0)
{
doCollect = false;
Wait();
}
doCollect = true;
if (!port.IsOpen)
{
port.Open();
port.NewLine = _NewLine;
port.ReadTimeout = 2000;
int number;
try { }
finally { }
port.Write("flashon\r");
while (doCollect && (_readCounter <= NumtoRead))
{
string s;
try
{
s = port.ReadLine();
}
catch
{
s = "-1";
}
int i;
if (int.TryParse(s, out i))
{
number = Convert.ToInt32(s, 10);
}
else
{
number = 0;
}
lock (thisLock) _data.Add(number);
_readCounter++;
}
port.Write("flashoff\r");
port.Close();
port.Dispose();
Wait(); Wait();
}
}
private void Wait()
{
System.Threading.Thread.Sleep(10);
System.Threading.Thread.SpinWait(1);
}
I don't get, why "ReadDataFromRS232" is beeing repeated until the timeout stops this task.
Thank you for any help :)
EDIT: Added some missing code.
As Dennis said the problem seemed to come from the missing volatile. It works now even though I have no idea why it didn't before.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
hi I'm new with wp8 I'm trying to develop an application . i have some problem to get from my
dictionary i don't know what's wrong here is my code
for (int i = 0; i < SharedInformation.tab.Length; i++)
{
lsCategorie.Clear();
for (int j = 0; j < SharedInformation.SharedLscitation.Count; j++)
{
if (SharedInformation.tab[i].Equals(SharedInformation.SharedLscitation[j].categorie.ToString()))
{
lsCategorie.Add(SharedInformation.SharedLscitation[j]);
}
}
SharedInformation.dic.Add(SharedInformation.tab[i], lsCategorie);
}
and my call
lsCitation = new List<Citation>();
lsCitation = (List<Citation>) SharedInformation.dic["amour"];
listbox.DataContext = lsCitation;
my complete code
public partial class MainPage : PhoneApplicationPage
{
private Popup popup;
private BackgroundWorker backroungWorker;
ShareStatusTask quotesh = new ShareStatusTask();
SmsComposeTask quotesms = new SmsComposeTask();
List<Citation> lsCitation = new List<Citation>();
List<Citation> lsCategorie = new List<Citation>();
// Constructeur
public MainPage()
{
InitializeComponent();
ShowSplash();
}
private void ShowSplash()
{
this.popup = new Popup();
this.popup.Child = new SplashScreen();
this.popup.IsOpen = true;
StartLoadingData();
}
private void StartLoadingData()
{
backroungWorker = new BackgroundWorker();
backroungWorker.DoWork += new DoWorkEventHandler(backroungWorker_DoWork);
backroungWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backroungWorker_RunWorkerCompleted);
backroungWorker.RunWorkerAsync();
}
void backroungWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
this.popup.IsOpen = false;
}
);
}
void backroungWorker_DoWork(object sender, DoWorkEventArgs e)
{
//here we can load data
Thread.Sleep(9000);
if (IsolatedStorageSettings.ApplicationSettings.Contains("data") == false)
{
InitializeComponent();
WebClient web = new WebClient();
web.DownloadStringCompleted += web_DownloadStringCompleted;
string uri = "http://quotesconsommation.azurewebsites.net/json/json.php";
web.DownloadStringAsync(new Uri(uri));
IsolatedStorageSettings.ApplicationSettings["data"] = 1;
IsolatedStorageSettings.ApplicationSettings["citation"] = lsCitation;
SharedInformation.SharedLscitation = lsCitation;
MessageBox.Show("" + NetworkInterface.GetIsNetworkAvailable() + "");
}
else
{
SharedInformation.SharedLscitation = IsolatedStorageSettings.ApplicationSettings["citation"] as List<Citation>;
}
for (int i = 0; i < SharedInformation.tab.Length; i++)
{
lsCategorie.Clear();
for (int j = 0; j < SharedInformation.SharedLscitation.Count; j++)
{
if (SharedInformation.tab[i].Equals(SharedInformation.SharedLscitation[j].categorie.ToString()))
{
lsCategorie.Add(SharedInformation.SharedLscitation[j]);
}
}
SharedInformation.dic.Add(SharedInformation.tab[i], lsCategorie);
}
}
void web_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var rootObject = JsonConvert.DeserializeObject<RootObject>(e.Result);
foreach (var blog in rootObject.citation)
{
lsCitation.Add(blog);
}
and where i'm making the call
List<Citation> lsCitation;
public TOUTES()
{
InitializeComponent();
lsCitation = new List<Citation>();
lsCitation = (List<Citation>) SharedInformation.dic["amour"];
listbox.DataContext = lsCitation;
}
mu sharedinformation class
public static class SharedInformation
{
public static Citation Sharedcitation;
public static List<Citation> SharedLscitation;
public static Dictionary<string, List<Citation>> dic = new Dictionary<string, List<Citation>>();
public static String[] tab = { "amour", "art et spectacle", "arts et creation", "bonheur", "cinema", "cultures", "famille", "fetes", "humour", "insolite", "livres et lettres", "musique", "nature", "philosophie", "pratique", "proverbes", "sagesse", "sciences", "sport et loisirs", "theatre", "travail" };
public static bool connectionstatus;
}
You can't call Clear() on the List<T> - you need to make a new one each time:
for (int i = 0; i < SharedInformation.tab.Length; i++)
{
// Make a new list, don't reuse it!
lsCategorie = new List<object>();
for (int j = 0; j < SharedInformation.SharedLscitation.Count; j++)
{
Since List<T> is a reference type (a class), each time you add, it doesn't add an entire copy of the list - it just adds the reference to the same list. Next time through your loop, you clear out the old list and add new items to it, etc.
As such, the behavior you'll see is that every key will have the items from the last tab's items, since they're all the exact same List<T> instance.
public class Program
{
static void Main(string[] args)
{
var myThread = new TestThread();
Thread t = new Thread(new ThreadStart(myThread.PrintName));
Thread t1 = new Thread(new ThreadStart(myThread.PrintType));
t.Start();
t1.Start();
Console.Read();
}
}
public class TestThread
{
public void PrintName()
{
for (int i = 1; i <= 50; i++)
{
Console.WriteLine("Name {0}", i);
}
}
public void PrintType()
{
for (int i = 100; i <= 180; i++)
{
Console.WriteLine("Type {0}", i);
}
}
}
Here How can i fixed it show that i can generate output in sequential i.e
first output of Name then only output of Type... Also I want to know about using Lock() in threads? where can i get good example. I am beginners in threading and need v.simple example.
Try this:
var myThread = new TestThread();
var x=Task.Factory.StartNew(() => myThread.PrintName());
x.ContinueWith(p => PrintType());
x.Wait();
You can look at this
There are multiple other articles, just google for 'introduction threading c#'.
The purpose of threads is to allow things to happen at the same time. If you want things to happen one after another (i.e. sequentially), then do not use threads:
var obj = new TestThread();
obj.PrintName();
obj.PrintType();
Console.Read();
Or put PrintName and PrintType into the same thread, in order to keep the UI responsive:
var myThread = new TestThread();
Thread t = new Thread(new ThreadStart(
() => {
myThread.PrintName(); myThread.PrintType();
}
));
t.Start();
// Do things in the UI meanwhile
for (i = 0; i < 100; i++) {
Console.WriteLine("UI thread {0}", i);
}
Console.Read();
//This will run two operation in sequence.
public class TestThread
{
public object obj = new object();
public void PrintName()
{
Monitor.Enter(obj);
for (int i = 1; i <= 50; i++)
{
Console.WriteLine("Name {0}", i);
}
Monitor.Exit(obj);
}
public void PrintType()
{
Monitor.Enter(obj);
for (int i = 100; i <= 180; i++)
{
Console.WriteLine("Type {0}", i);
}
Monitor.Exit(obj);
}
}
That will do the trick, you should read carefully and try to do it with 3 loops by yourself:
private static void SimpleLockTest()
{
Task[] myTasks = new Task[2];
myTasks[0] = Task.Factory.StartNew(() =>
{
LockTestThreadOne();
});
myTasks[1] = Task.Factory.StartNew(() =>
{
LockTestThreadTwo();
});
Task.WaitAll(myTasks);
Console.WriteLine("Done, press ENTER to quit");
Console.ReadLine();
}
private static object locker = new object();
private static void LockTestThreadOne()
{
Monitor.Enter(locker);
for (int i = 1; i <= 50; i++)
{
Console.WriteLine("Name {0}", i);
Monitor.Pulse(locker);
Monitor.Wait(locker);
}
Monitor.Exit(locker);
}
private static void LockTestThreadTwo()
{
Monitor.Enter(locker);
for (int i = 100; i <= 180; i++)
{
Console.WriteLine("Type {0}", i);
Monitor.Pulse(locker);
Monitor.Wait(locker, 10);
}
Monitor.Exit(locker);
}
I have two words:
Source: John
ConvertTo: Jack
and I want to show the effect of convert all letters from "Source" at the same time to the "ConvertTo" word. I already create a program to accomplish that but processing one letter at a time, to show the effect I use Threads, the thing is that to process all letters at the same time I suppose I need one thread per letter, and every thread will call the same function that process the letter, and I use global variables.
Here is the code (works only for texts with same lenght):
private void button1_Click(object sender, EventArgs e)
{
lblResult.Text = "";
lblResult2.Text = "";
ThreadPool.QueueUserWorkItem(new WaitCallback(Process));
}
int movement = 0;
string CumulateText;
private void Process(object stateinfo)
{
int value;
int operation; //0->[+] 1->[-]
CumulateText = "";
for (int i = 0; i <= textBox1.Text.Length - 1; i++)
{
if (textBox1.Text[i] != ' ')
{
value = (char)textBox1.Text[i] - (char)textBox2.Text[i];
if (value >= 0)
operation = 1;
else
operation = 0;
for (int ii = 0; ii <= Math.Abs(value); ii++)
{
if (operation == 1)
movement = (char)textBox1.Text[i] - ii;
else
movement = (char)textBox1.Text[i] + ii;
this.Invoke(new EventHandler(ShowMovement));
System.Threading.Thread.Sleep(10);
}
}
CumulateText += textBox2.Text[i].ToString();
}
}
private void ShowMovement(object sender, EventArgs e)
{
lblResult.Text = CumulateText + Convert.ToString((char)movement);
}
I hope I made myself understood.
please any advise to accomplish that.
thanks
To clarify more what I want to accomplish here is an example:
Source: John
ConvertTo: Jack
J - same J
o - decrease till a (o, n, m, ..., a)
h - decrease till c (h, g, f, ..., c)
n - decrease till k (n, m, l, k)
I once had to do something similar for a small little project I was working on for fun.
I do not see why you would need to create a thread for each letter to create a transition between two words unless I'm not understanding what you are pretending to do correctly.
Check and study the following code, see if its any help:
static class Program
{
static void Main()
{
TextTranstition transition = new TextTranstition();
transition.TransitionFinished += TransitionTicked;
transition.TransitionTicked += TransitionTicked;
transition.StartTransition("AmazingWordTransition", "MyNewWordAppearing", 100);
Thread.CurrentThread.Join();
Console.ReadKey();
}
public static void TransitionTicked(object sender, TranstitionEventArgs e)
{
Console.Clear();
Console.Write(e.TransitionText);
}
}
public class TranstitionEventArgs : EventArgs
{
private readonly string transitionText;
public string TransitionText { get { return this.transitionText; } }
public TranstitionEventArgs(string transitionText)
{
this.transitionText = transitionText;
}
}
public class TextTranstition
{
private struct StartInfo
{
public StartInfo(string initialText, string finalText, int timeStep)
{
this.initialText = initialText;
this.finalText = finalText;
this.timeStep = timeStep;
}
private readonly string initialText;
public string InitialText { get { return this.initialText; } }
private readonly string finalText;
public string FinalText { get { return this.finalText; } }
private readonly int timeStep;
public int TimeStep { get { return this.timeStep; } }
}
public EventHandler<TranstitionEventArgs> TransitionFinished;
public EventHandler<TranstitionEventArgs> TransitionTicked;
public void StartTransition(string initialText, string finalText, int timeStep)
{
StartInfo startInfo = new StartInfo(initialText, finalText, timeStep);
Thread t = new Thread(startTransition);
t.Start(startInfo);
}
private void startTransition(object info)
{
StartInfo startInfo = (StartInfo)info;
string initialText = startInfo.InitialText;
string finalText = startInfo.FinalText;
if (initialText.Length < finalText.Length)
{
initialText = initialText.PadRight(finalText.Length);
}
if (TransitionTicked != null) TransitionTicked(this, new TranstitionEventArgs(initialText));
while ((initialText = transition(initialText, finalText)) != finalText)
{
Thread.Sleep(startInfo.TimeStep);
if (TransitionTicked != null) TransitionTicked(this, new TranstitionEventArgs(initialText));
}
if (TransitionFinished != null) TransitionFinished(this, new TranstitionEventArgs(finalText));
}
private string transition(string initialText, string finalText)
{
StringBuilder b = new StringBuilder(finalText.Length);
for (int i = 0; i < finalText.Length; i++)
{
char c = initialText[i];
int charCode = (int)c;
if (c != finalText[i])
{
if (charCode == 122 || charCode==32) charCode = 65;
else if (charCode == 90) charCode = 97;
else
{
charCode += 1;
}
}
b.Append((char)charCode);
}
return b.ToString();
}
}
Use BackgroudWorker for this kind of stuff.