I'm working on a C# UWP APP and I need to communicate with many devices using
an USB port as Serial Port. After that I will convert the communication to RS485 to communicate with the other devices. Until now, I have create a class that will make all comunications between my devices and I can sent a trama between my devices.
My problem at this point is that after sending some startup frames, the application changes the page and from that moment gives me the following exception in my ReadAsync method:
**
System.Exception occurred HResult=-2147023901 Message=The I/O
operation was canceled due to a module output or an application
request. (Exception from HRESULT: 0x800703E3) Source=mscorlib
StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at DrDeliver.CComm.d__31.MoveNext() InnerException:
**
Exception Picture
I already have this problem for a few days and I can't get over it.
I wonder if anyone can figure out where the problem is.
Another question I would like to ask is if anyone knows of any method that allows me to make this communication synchronously.
UPDATE 1
The entire class for communicatons:
public class CComm : IDisposable
{
EventLogDB _eldb = new EventLogDB();
ParameterDB _pdb = new ParameterDB();
cParameter _cParam = new cParameter();
DataReader _dataReaderObject = null;
private DispatcherTimer mTimer;
private int num;
public bool FlagComm { set; get; }
public static string InBuffer { set; get; }
public bool busyFlag = false;
public CancellationTokenSource _readCancellationTokenSource = new CancellationTokenSource();
private DeviceInformationCollection DeviceInformation { set; get; }
private static SerialDevice SerialPort { set; get; }
// Define a delegate
public delegate void CheckReadEventHandler(object source, EventArgs args);
// Define an event based on that delegate
public event CheckReadEventHandler CheckRead;
// Raise an event
protected virtual void OnChecRead()
{
CheckRead?.Invoke(this, EventArgs.Empty);
}
private async Task OpenComm()
{
try
{
busyFlag = true;
//_cParam = _pdb.getParameters();
string selectedPortId = null;
string aqs = SerialDevice.GetDeviceSelector();
DeviceInformation = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
foreach (var devInfo in DeviceInformation)
{
if (devInfo.Name == "USB-RS485 Cable")
{
selectedPortId = devInfo.Id;
}
}
if (selectedPortId != null)
{
SerialPort = await SerialDevice.FromIdAsync(selectedPortId);
if (SerialPort != null)
{
SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1500);
SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
SerialPort.BaudRate = 9600;
SerialPort.Parity = SerialParity.None;
SerialPort.StopBits = SerialStopBitCount.One;
SerialPort.DataBits = 8;
FlagComm = true;
}
else
{
var status = DeviceAccessInformation.CreateFromId(selectedPortId).CurrentStatus;
FlagComm = false;
_eldb.attachEvent("E1002", "Starting Comunication Failed: " + status);
//ContentDialog noSerialDevice = new ContentDialog()
//{
// Title = "No Serial Connection",
// Content = "Check connection and try again. App Closing.",
//};
//await noSerialDevice.ShowAsync();
//this.Dispose();
}
InitTool();
await ActivateListen();
busyFlag = false;
}
}
catch (Exception ex)
{
_eldb.attachEvent("E1cC", ex.Message);
}
}
private async Task Listen()
{
try
{
if (SerialPort != null)
{
busyFlag = true;
_dataReaderObject = new DataReader(SerialPort.InputStream);
await ReadAsync(_readCancellationTokenSource.Token);
busyFlag = false;
}
}
catch (Exception ex)
{
}
}
//using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000)))
//{
// await dataReaderObject.LoadAsync(1024).AsTask(cts.Token);
//}
private async Task ReadAsync(CancellationToken cancellationToken)
{
busyFlag = true;
const uint readBufferLength = 1024; // only when this buffer would be full next code would be executed
var loadAsyncTask = _dataReaderObject.LoadAsync(readBufferLength).AsTask(cancellationToken); // Create a task object
_dataReaderObject.InputStreamOptions = InputStreamOptions.ReadAhead;
var bytesRead = await loadAsyncTask; // Launch the task and wait until buffer would be full
if (bytesRead > 0)
{
InBuffer += _dataReaderObject.ReadString(bytesRead);
OnChecRead();
}
busyFlag = false;
}
private async void WriteComm(string str2Send)
{
using (var dataWriter = new DataWriter(SerialPort.OutputStream))
{
dataWriter.WriteString(str2Send);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
}
private async Task ActivateListen()
{
while (FlagComm)
{
await Listen();
}
}
private void dispatcherTimer_Tick(object sender, object e)
{
_eldb.attachEvent("SYSTEM", "Checking ADDR: " + num);
SendComm(num++, 5);
if (num == 5)
{
mTimer.Stop();
_eldb.attachEvent("SYSTEM", "Modules Checking Finished.");
busyFlag = false;
}
}
public void InitTool()
{
busyFlag = true;
_eldb.attachEvent("SYSTEM", "Setting Parameters.");
// Get Parameters
if (_pdb.GetParameters() == null)
{
// Set Default Parameters
_cParam.SetParam();
// Insert Default parameters in database
_pdb.Insert(_cParam);
// Update Parameters Object
_cParam = _pdb.GetParameters();
}
else
{
// Update Parameters Object
_cParam = _pdb.GetParameters();
}
// Check Addresses in Line
_eldb.attachEvent("SYSTEM", "Start Verifiyng.");
num = 0;
mTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(4000) };
mTimer.Tick += dispatcherTimer_Tick;
mTimer.Start();
}
public async void StartSerialComm()
{
try
{
await OpenComm();
}
catch (Exception ex)
{
_eldb.attachEvent("E7cC", ex.Message);
}
}
public void SendComm(params int[] list)
{
try
{
_cParam = _pdb.GetParameters();
string toSend = "";// = "A" + list[0] + "#";
switch (list[1])
{
case 0:
// Send Initialazation command
toSend = "##" + list[0] + "#" + list[1] + "##";
break;
case 1:
// List of parameters (minPower, maxPower, ramPercent, initSpeed)
toSend = "##" + list[0] + "#" + list[1] + "#" + _cParam.minPower + "#" +
_cParam.maxPower + "#" + _cParam.percRamp + "#" + _cParam.initSpeed + "##";
break;
case 2:
// Send Status Request
toSend = "##" + list[0] + "#" + list[1] + "##";
break;
case 3:
// Send a move Request
toSend = "##" + list[0] + "#" + list[1] + "#" + list[2] + "##";
break;
case 4:
// Send a Error Request
toSend = "##" + list[0] + "#" + list[1] + "##";
break;
case 5:
// Send a start check
toSend = "##" + list[0] + "#" + list[1] + "##";
break;
default:
_eldb.attachEvent("E1004", "Wrong Function Command.");
break;
}
if (toSend != "")
{
WriteComm(toSend);
}
else
{
_eldb.attachEvent("E1003", "Wrong String comunication.");
}
}
catch (Exception ex)
{
_eldb.attachEvent("E8cC", ex.Message);
}
}
public void Dispose()
{
try
{
if (SerialPort == null) return;
FlagComm = false;
SerialPort.Dispose();
SerialPort = null;
if (_dataReaderObject == null) return;
_readCancellationTokenSource.Cancel();
_readCancellationTokenSource.Dispose();
}
catch (Exception ex)
{
_eldb.attachEvent("E6cC", ex.Message);
}
}
}
Main Page:
public sealed partial class MainPage : Page
{
CComm _cC = new CComm();
EventLogDB _eldb = new EventLogDB();
procTrama _cProcTrama = new procTrama();
private DispatcherTimer mTimer;
public MainPage()
{
try
{
InitializeComponent();
// Get the application view title bar
ApplicationViewTitleBar appTitleBar = ApplicationView.GetForCurrentView().TitleBar;
// Make the title bar transparent
appTitleBar.BackgroundColor = Colors.Transparent;
// Get the core appication view title bar
CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
/*
ExtendViewIntoTitleBar
Gets or sets a value that specifies whether this title
bar should replace the default window title bar.
*/
// Extend the core application view into title bar
coreTitleBar.ExtendViewIntoTitleBar = true;
mTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(5000) };
mTimer.Tick += dispatcherTimer_Tick;
mTimer.Start();
_eldb.attachEvent("S1027", "Init Started...");
// Start comunication
_cC.StartSerialComm();
// Reference for CheckRead Event
_cC.CheckRead += OnCheckRead;
}
catch (Exception ex)
{
_eldb.attachEvent("MainP", ex.Message);
}
}
private void dispatcherTimer_Tick(object sender, object e)
{
if (!_cC.busyFlag)
{
Frame.Navigate(typeof(InitPage), null);
mTimer.Stop();
}
}
public void OnCheckRead(object source, EventArgs e)
{
try
{
if (CComm.InBuffer == null) return;
_cProcTrama.ProcessTrama(CComm.InBuffer);
CComm.InBuffer = "";
}
catch (Exception ex)
{
_eldb.attachEvent("OnCheckRead: ", ex.Message);
}
}
}
INIT Page:
public partial class InitPage : Page
{
CComm _cC = new CComm();
EventLogDB _eldb = new EventLogDB();
procTrama _cProcTrama = new procTrama();
public InitPage()
{
this.InitializeComponent();
_eldb.attachEvent("S1000", "System Started.");
// Reference for CheckRead Event
_cC.CheckRead += OnCheckRead;
}
private void button_Click(object sender, RoutedEventArgs e)
{
_eldb.attachEvent("S1001", "Login Activated.");
Frame.Navigate(typeof(Page1), null);
}
public void OnCheckRead(object source, EventArgs e)
{
if (CComm.InBuffer == null) return;
_eldb.attachEvent("OnCheckRead: ", CComm.InBuffer);
_cProcTrama.ProcessTrama(CComm.InBuffer);
}
}
Login Page where i more frequently the error occur:
public sealed partial class Page1 : Page
{
private CComm _cC = new CComm();
private procTrama _cProcTrama = new procTrama();
EventLogDB _eldb = new EventLogDB();
public Page1()
{
this.InitializeComponent();
// Reference for CheckRead Event
_cC.CheckRead += OnCheckRead;
user = null;
pass = null;
user_pass = 0;
}
private const int userLimit = 5;
private const int passLimit = 5;
private const char passChar = '*';
public string user
{
get; set;
}
public string pass
{
get; set;
}
public int user_pass
{
get; set;
}
private void execute(char val)
{
string aux = null;
if (user_pass == 1)
{
if (user == null)
user = val.ToString();
else
{
if (user.Length <= userLimit)
user = user + val;
}
userBtn.Content = user;
}
else
{
if (user_pass == 2)
{
if (pass == null)
pass = val.ToString();
else
{
if (pass.Length <= passLimit)
pass = pass + val;
}
for (int i = 0; i < pass.Length; i++)
aux = aux + passChar;
passBtn.Content = aux;
}
}
}
private void key1Btn_Click(object sender, RoutedEventArgs e)
{
execute('1');
}
private void key2Btn_Click(object sender, RoutedEventArgs e)
{
execute('2');
}
private void key3Btn_Click(object sender, RoutedEventArgs e)
{
execute('3');
}
private void key4Btn_Click(object sender, RoutedEventArgs e)
{
execute('4');
}
private void key5Btn_Click(object sender, RoutedEventArgs e)
{
execute('5');
}
private void key6Btn_Click(object sender, RoutedEventArgs e)
{
execute('6');
}
private void key7Btn_Click(object sender, RoutedEventArgs e)
{
execute('7');
}
private void key8Btn_Click(object sender, RoutedEventArgs e)
{
execute('8');
}
private void key9Btn_Click(object sender, RoutedEventArgs e)
{
execute('9');
}
private void key0Btn_Click(object sender, RoutedEventArgs e)
{
execute('0');
}
private void keyEntrarBtn_Click(object sender, RoutedEventArgs e)
{
if (pass == "123" && user == "123")
{
_eldb.attachEvent("S1002", "User Login: " + user);
Frame.Navigate(typeof(Page2), null);
}
user_pass = 0;
passBtn.Content = "Insirir Código";
userBtn.Content = "Inserir Utilizador";
}
private void keyApagarBtn_Click(object sender, RoutedEventArgs e)
{
pass = null;
user = null;
user_pass = 0;
passBtn.Content = "Inserir Código";
userBtn.Content = "Inserir Utilizador";
_eldb.attachEvent("S1003", " User data cleared.");
}
private void userBtn_Click(object sender, RoutedEventArgs e)
{
user_pass = 1;
userBtn.Content = "";
_eldb.attachEvent("S1004", "User button clicked.");
}
private void passBtn_Click(object sender, RoutedEventArgs e)
{
user_pass = 2;
passBtn.Content = "";
_eldb.attachEvent("S1005", "Pass button clicked.");
}
private void exitBtn_Click(object sender, RoutedEventArgs e)
{
_eldb.attachEvent("S1006", "Page1 exit button clicked.");
Frame.Navigate(typeof(InitPage), null);
}
public void OnCheckRead(object source, EventArgs e)
{
try
{
if (CComm.InBuffer == null) return;
_eldb.attachEvent("OnCheckRead: ", CComm.InBuffer);
_cProcTrama.ProcessTrama(CComm.InBuffer);
}
catch (Exception ex)
{
_eldb.attachEvent("OnCheckRead: ", ex.Message);
}
}
}
Related
I am developing a C# program that works as a websock server and controls a SIP phone (I am using the excellent voipsdk library). I am new to C# and am confused on how to integrate the two.
My Websock server class is this:
public class Echo : WebSocketBehavior {
protected override void OnMessage(MessageEventArgs e) {
Console.WriteLine("Received message from client " + e.Data);
Send(decode(e.Data));
}
protected String decode(String json) {
var msg = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine("\tCommand Received:" + msg.command);
string cmd = Convert.ToString(msg.command);
string resp = "";
switch (cmd) {
case "TEST":
Console.WriteLine("\t\tTest Invoked");
resp = "Testing ..";
break;
case "DIAL":
string number = Convert.ToString(msg.number);
Console.WriteLine("\t\tDial:" + number);
resp = "Dialing " + number;
break;
case "HANGUP":
Console.WriteLine("\t\tHangup!");
resp = "Hanging Up";
break;
}
return (resp);
}
}
and my phone class
class Phone {
static ISoftPhone softphone; // softphone object
static IPhoneLine phoneLine; // phoneline object
static IPhoneCall call;
static Microphone microphone;
static Speaker speaker;
static MediaConnector connector;
static PhoneCallAudioSender mediaSender;
static PhoneCallAudioReceiver mediaReceiver;
public static void startPhone(string ext, string pwd, string host, int port) {
softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000);
var registrationRequired = true;
/**
var ext = "1008";
var pwd = "passw0rd";
var host = "192.168.1.234";
var port = 5060;
**/
var account = new SIPAccount(registrationRequired, ext, ext, ext, pwd, host, port);
RegisterAccount(account);
microphone = Microphone.GetDefaultDevice();
speaker = Speaker.GetDefaultDevice();
mediaSender = new PhoneCallAudioSender();
mediaReceiver = new PhoneCallAudioReceiver();
connector = new MediaConnector();
}
static void RegisterAccount(SIPAccount account) {
try {
phoneLine = softphone.CreatePhoneLine(account);
phoneLine.RegistrationStateChanged += line_RegStateChanged;
softphone.RegisterPhoneLine(phoneLine);
}
catch (Exception ex) {
Console.WriteLine("Error during SIP registration: " + ex);
}
}
static void line_RegStateChanged(object sender, RegistrationStateChangedArgs e) {
if (e.State == RegState.NotRegistered || e.State == RegState.Error)
Console.WriteLine("Registration failed!");
if (e.State == RegState.RegistrationSucceeded) {
Console.WriteLine("Registration succeeded - Online!");
// CreateCall();
}
}
public static void CreateCall(string numberToDial) {
// var numberToDial = "1000";
call = softphone.CreateCallObject(phoneLine, numberToDial);
call.CallStateChanged += call_CallStateChanged;
call.Start();
}
private static void SetupDevices() {
connector.Connect(microphone, mediaSender);
connector.Connect(mediaReceiver, speaker);
mediaSender.AttachToCall(call);
mediaReceiver.AttachToCall(call);
microphone.Start();
speaker.Start();
}
static void call_CallStateChanged(object sender, CallStateChangedArgs e) {
Console.WriteLine("Call state: {0}.", e.State);
if (e.State == CallState.Answered)
SetupDevices();
}
}
My problem is that I need to call the phone class from within the Websocket class in the "Protected String decode (string json) " function shown above..
How do I call the Phone class from within this function? Where do I need to declare the instance of the phone class?
I'm trying to develop a warning if I try to connect to a specific SSID and some waiting time has passed. I've tried with a Timer class but there is some issues with Task and Threads I can't resolve.
This is my Wifi class in Xamarin.Droid
public class Wifi : Iwifi
{
private Context context;
private static WifiManager _manager;
private MyReceiver _receiver;
public void Initialize()
{
context = Android.App.Application.Context;
_manager = (WifiManager)context.GetSystemService(Context.WifiService);
_receiver = new MyReceiver();
}
public void Register()
{
IntentFilter intents = new IntentFilter();
intents.AddAction(WifiManager.ScanResultAction);
intents.AddAction(WifiManager.NetworkStateChangedAction);
context.RegisterReceiver(_receiver, intents);
}
public void Unregister()
{
context.UnregisterReceiver(_receiver);
}
public void ScanWirelessDevices()
{
_manager.StartScan();
}
public string GetConnectionSSID()
{
return _manager.ConnectionInfo.SSID;
}
public void ConnectToSSID(string SSID, string pwd)
{
if (!_manager.IsWifiEnabled)
{
_manager.SetWifiEnabled(true);
}
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.Ssid = '"' + SSID + '"';
if (pwd.Empty)
{
wifiConfiguration.AllowedKeyManagement.Set((int)KeyManagementType.None);
}
else
{
//Configuration for protected Network
}
var addNet = _manager.AddNetwork(wifiConfiguration);
if (addNet == -1)
{
_manager.Disconnect();
_manager.EnableNetwork(addNet, true);
_manager.Reconnect();
return;
}
var list = _manager.ConfiguredNetworks;
foreach (WifiConfiguration conf in list)
{
if (conf.Ssid.Equals('"' + SSID + '"'))
{
_manager.Disconnect();
_manager.EnableNetwork(conf.NetworkId, true);
_manager.Reconnect();
return;
}
}
}
public class MyReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action.Equals(WifiManager.ScanResultAvailableAction))
{
IList<ScanResult> scanResult = _manager.ScanResult;
App.Networks.NetworksList.Clear();
foreach (ScanResult result in scanResult)
{
App.Networks.NetworksList.Add(result.Ssid);
}
}
}
}
}
Then this is a part of App class in Xamarin.Forms
public partial class App: Application
{
private static ...
.
.
.
private static string _selectedSSID;
private static MainDetail _pageDetail;
public static IWifi WifiManager { get; } = DependencyService.Get<Iwifi>();
public static string SelectedSSID { get { return _selectedSSID; } set { _selectedSSID = value; } }
public static MainDetail PageDetail { get { return _pageDetail; } }
public App()
{
InitializeComponent();
WifiManager.Initialize();
WifiManager.Register();
InitViews();
MainPage = _mainPage;
Connectivity.ConnectivityChanged += NetworkEvents;
NetSearch();
}
.
.
.
public void NetSearch()
{
Task.Run(async () =>
{
while (true)
{
WifiManager.ScanWirelessDevices();
await Task.Delay(Utility.SCAN_WIFI_TIMER); //waiting 31000 milliseconds because of Scanning throttling
}
});
}
public void NetworkEvents(object sender, ConnectivityChangedEventArgs e)
{
MainMaster master = (MainMaster)_mainPage.Master;
if (e.NetworkAccess == NetworkAccess.Unknown)
{
Debug.WriteLine("Network Access Unknown " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.None)
{
Debug.WriteLine("Network Access None " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.Local)
{
Debug.WriteLine("Network Access Local " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.Internet)
{
if(selectedSSID == Wifimanager.GetConnectionInfo())
{
//WE CONNECTED!!
//Now I want to stop the Timeout Timer to attempt
}
}
if (e.NetworkAccess == NetworkAccess.ConstrainedInternet)
{
Debug.WriteLine("Network Access Constrainde Internet " + e.ToString());
}
}
}
And part of Detail page class in which I start the event of connection and where I want to start also the timeout timer
public partial class MainDetail : ContentPage
{
.
.
.
public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
ImageCell item = (ImageCell)e.SelectedItem;
App.SelectedSSID = item.Text;
App.WifiManager.ConnectToSSID(item.Text, "");
ActivityIndicator(true);
//Now the timer should start.
//And call PageDetail.ActivityIndicator(false) and warning the user if the timeout go to 0.
listView.SelectedItem = null;
}
}
I tried with the Timers Timer class but doesn't work.. any suggestion?
Ok I figured a solution! Instead of using Thread and Task, I used Device.StartTimer.
In the event on the DetailPage I wrote:
public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
ImageCell item = (ImageCell)e.SelectedItem;
App.SelectedSSID = item.Text;
App.WifiManager.ConnectToSSID(item.Text, "");
ActivityIndicator(true);
Device.StartTimer(TimeSpan.FromSeconds(10), () => //Waiting 10 second then if we are not connected fire the event.
{
Device.BeginInvokeOnMainThread(() =>
{
if (App.IsLogout) //variable I use to check if I can do the logout or not
{
ActivityIndicator(false);
App.SelectedSSID = "";
//My message to users "Fail to connect"
}
});
return false;
});
listView.SelectedItem = null;
}
So, I have a win form where I have to search for a string in a text file and display the line number and the entire line if I found the string. The search has to be multithreaded and all the line numbers and the lines must be on a listview. For example if the word "language" is in line number 60 , the listview must display:
60 "the line has the word language"
I have used the background worker in this regard but I am not being able to display the correct line number and the lines. Firstly, one line is being displayed multiple times and secondly, the line number is always coming to be 0. However, when I output the result in Console, the result is correct. I think I am making some error in putting the result into the listview.
Here' s my main form.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// private bool start_cancel;
bool bln = true;
private void StartCancelbtn_Click(object sender, EventArgs e)
{
if (bln)
text2();
else
text1();
bln = !bln;
}
private void text1()
{
StartCancelbtn.Text = "Start";
this.backgroundWorker1.CancelAsync();
}
private void text2()
{
StartCancelbtn.Text = "Cancel";
StartThread();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
System.ComponentModel.BackgroundWorker worker;
worker = (System.ComponentModel.BackgroundWorker)sender;
// Get the Words object and call the main method.
main_work WC = (main_work)e.Argument;
WC.CountWords(worker, e);
if (worker.CancellationPending)
{
e.Cancel = true;
// break;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
main_work.ReportState state =
(main_work.ReportState)e.UserState;
ListViewItem l1 = new ListViewItem();
l1.Text = state.LinesCounted.ToString();
l1.SubItems.Add(state.line);
listView1.Items.Add(l1);
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
MessageBox.Show("Error: " + e.Error.Message);
else if (e.Cancelled)
MessageBox.Show("Word counting canceled.");
else
MessageBox.Show("Finished counting words.");
}
private void StartThread()
{
main_work WC = new main_work();
WC.CompareString = this.searchtext.Text;
WC.SourceFile = this.filenametextbox.Text;
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync(WC);
}
private void browsebtn_Click(object sender, EventArgs e)
{
using (OpenFileDialog brw = new OpenFileDialog())
{
if (brw.ShowDialog() == DialogResult.OK)
{
using (StreamReader sr = new StreamReader(brw.FileName))
{
filenametextbox.Text = brw.FileName.ToString();
}
}
}
}
}
}
Here is my main_work class where the actual comparison is happening:
class main_work
{
public class ReportState
{
public int LinesCounted;
public string line;
}
Queue q = new Queue();
public string SourceFile;
public string CompareString;
public string line2 ;
public int linenumber=0;
public int linenumber1 = 0;
int LinesCounted1;
// public string line2;
public void CountWords(
System.ComponentModel.BackgroundWorker worker,
System.ComponentModel.DoWorkEventArgs e)
{
// Initialize the variables.
ReportState state = new ReportState();
string line1 = "";
int elapsedTime = 1;
DateTime lastReportDateTime = DateTime.Now;
if (CompareString == null ||
CompareString == System.String.Empty)
{
MessageBox.Show("Please Enter a string to be searched");
}
else
{
// 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
{
line1 = myStream.ReadLine();
line2 = (CountInString(line1, CompareString));
LinesCounted1 = (linenumbercount(line1, CompareString, linenumber1));
// Raise an event so the form can monitor progress.
int compare = DateTime.Compare(
DateTime.Now, lastReportDateTime.AddSeconds(elapsedTime));
if (compare > 0)
{
state.LinesCounted = LinesCounted1;
state.line = line2;
worker.ReportProgress(0, state);
lastReportDateTime = DateTime.Now;
}
System.Threading.Thread.Sleep(1);
}
}
// Report the final count values.
state.LinesCounted = LinesCounted1;
state.line = line1;
worker.ReportProgress(0, state);
lastReportDateTime = DateTime.Now;
}
}
}
private string CountInString(
string SourceString,
string CompareString)
{
if (SourceString.Contains(CompareString))
{
line2 = SourceString;
Console.WriteLine(SourceString);
}
return line2;
}
private int linenumbercount(
string SourceString,
string CompareString,
int linenumber)
{
// Lines = 0;
if (SourceString == null)
{
return 0;
}
if (SourceString.Contains(CompareString))
{
Console.WriteLine(linenumber);
}
linenumber++;
return linenumber;
}
}
Any feedback will be helpful. Please let me know what I am doing wrong and where is it that I am making a mistake as I am new to background worker and multithreading. Thanks.
I want to rerun thread when it finish working. I have two programs. One in Windows Form and second in cmd. Windows Form program run program in cmd.
I tried use while(true) and if with: process.HasExited, .WaitForExit, .Join on thred, .IsBusy and rerun method on RunWorkerCompleted. But it's doesn't work.
BgWorker code (action on button click):
backgroundWorker1.RunWorkerAsync();
backgroundWorker1.DoWork += new DoWorkEventHandler(uruchomWatek);
Function whitch I want to rerun thread
private void uruchomWatek(object sender, DoWorkEventArgs e)
{
String polaczenieZDB = config.Default.adresDb + ";" + config.Default.nazwaDb + ";" + config.Default.login + ";" + config.Default.haslo;
//przygotowuję proces
Process pr = new Process();
ProcessStartInfo prs = new ProcessStartInfo();
//uruchamiam cmd
prs.FileName = "cmd";
// /c START uruchamia program w cmd, przekazuję tutaj prametry
prs.Arguments = " /c START " + " " + #sciezkaDoSlaveTextBox.Text + " " + ipAdresTextBox.Text + " "
+ numerPortuTextBox.Text + " " + polaczenieZDB + " " + pobierzZadaniaDoSpr();
pr.StartInfo = prs;
//uruchamiam proces w nowym wątku
ThreadStart ths = new ThreadStart(() => pr.Start());
Thread th = new Thread(ths);
th.IsBackground = true;
th.Start();
}
This class may help you through this purpose :
public class BackgroundThread : BackgroundWorker
{
public BackgroundThread()
{
this.WorkerSupportsCancellation = true;
}
protected override void OnDoWork(DoWorkEventArgs e)
{
try
{
base.OnDoWork(e);
}
catch (Exception exception)
{
//Log Exception
}
}
public void Run()
{
if (this.IsBusy)
return;
this.RunWorkerAsync();
}
public void Stop()
{
this.CancelAsync();
this.Dispose(true);
}
}
EDIT :
If you want to use your class as a timer and do the task in intervals the following class may comes really handy.
public class BackgroundTimer : BackgroundWorker
{
private ManualResetEvent intervalManualReset;
private enum ProcessStatus { Created, Running, JobCompleted, ExceptionOccured };
private ProcessStatus processStatus = new ProcessStatus();
public int Interval { get; set; }
public BackgroundTimer()
{
this.processStatus = ProcessStatus.Created;
this.WorkerSupportsCancellation = true;
this.Interval = 1000;
}
protected override void OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
{
base.OnRunWorkerCompleted(e);
if (processStatus == ProcessStatus.ExceptionOccured)
// Log ...
processStatus = ProcessStatus.JobCompleted;
}
protected override void OnDoWork(DoWorkEventArgs e)
{
while (!this.CancellationPending)
{
try
{
base.OnDoWork(e);
this.Sleep();
}
catch (Exception exception)
{
// Log ...
this.processStatus = ProcessStatus.ExceptionOccured;
this.Stop();
}
}
if (e != null)
e.Cancel = true;
}
public void Start()
{
this.processStatus = ProcessStatus.Running;
if (this.IsBusy)
return;
this.intervalManualReset = new ManualResetEvent(false);
this.RunWorkerAsync();
}
public void Stop()
{
this.CancelAsync();
this.WakeUp();
this.Dispose(true);
}
public void WakeUp()
{
if (this.intervalManualReset != null)
this.intervalManualReset.Set();
}
private void Sleep()
{
if (this.intervalManualReset != null)
{
this.intervalManualReset.Reset();
this.intervalManualReset.WaitOne(this.Interval);
}
}
public void Activate()
{
if (!this.IsBusy)
// Log ...
this.Start();
}
}
EDIT 2 :
Usage :
sendThread = new BackgroundThread();
sendThread.DoWork += sendThread_DoWork;
sendThread.Run();
void sendThread_DoWork(object sender, DoWorkEventArgs e)
{
...
}
I have a problem. I am trying to modify an app I made some time ago and it Works still on WP Phone, but now I try to run it get these errors:
On await I get:
cannot await 'void'.
When I change void to task the error is still
Cannot await 'void'
I don't even have void any more.
Can somebody help me ?
namespace StreamUploadDownload
{
using System.Threading;
public partial class Page1 : PhoneApplicationPage
{
private PhotoCamera _cam;
private double _canvasWidth;
private double _canvasHeight;
private MediaLibrary _library = new MediaLibrary();
public int count = 100;
private static readonly string[] scopes = new string[] { "wl.signin", "wl.basic", "wl.offline_access", "wl.skydrive_update", "wl.skydrive" };
string comboValue;
private LiveConnectClient liveClient;
public int x = 0;
public int y = 0;
public string FileText { get; set; }
public int ComboNumber { get; set; }
public int ConnectionOK { get; set; }
public Page1()
{
InitializeComponent();
}
private void OnSessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
this.liveClient = (e.Status == LiveConnectSessionStatus.Connected) ? new LiveConnectClient(e.Session) : null;
if (e.Status == LiveConnectSessionStatus.Connected)
{
btnSignin.Visibility = Visibility.Collapsed;
Pildista.Visibility = Visibility.Visible;
//Pildista2K.Visibility = Visibility.Visible;
Pildista.Content = "Pildista";
}
else
{
Pildista.Visibility = Visibility.Collapsed;
//Pildista2K.Visibility = Visibility.Collapsed;
btnSignin.Visibility = Visibility.Visible;
}
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if ((PhotoCamera.IsCameraTypeSupported(CameraType.Primary) == true) ||
(PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) == true))
{
if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary))
{
_cam = new Microsoft.Devices.PhotoCamera(CameraType.Primary);
_cam.Initialized += new EventHandler<CameraOperationCompletedEventArgs>(cam_Initialized);
_cam.CaptureImageAvailable += new EventHandler<ContentReadyEventArgs>(cam_CaptureImageAvailable);
viewfinderBrush.SetSource(_cam);
//CameraButtons.ShutterKeyPressed += OnButtonFullPress;
base.OnNavigatedTo(e);
if (PhoneApplicationService.Current.State.ContainsKey("Text"))
{
txtvalue.Text = (string)PhoneApplicationService.Current.State["Text"];
FileText = txtvalue.Text;
}
if (PhoneApplicationService.Current.State.ContainsKey("index"))
{
ComboNumber = (int)PhoneApplicationService.Current.State["index"];
}
else
{
// The camera is not supported on the device.
this.Dispatcher.BeginInvoke(delegate()
{
// Write message.
});
// Disable UI.
AFButton.IsEnabled = false;
}
}
}
}
private double GetCameraAspectRatio()
{
IEnumerable<Size> resList = _cam.AvailableResolutions;
if (resList.Count<Size>() > 0)
{
Size res = resList.ElementAt<Size>(0);
return res.Width / res.Height;
}
return 1;
}
void cam_Initialized(object sender, Microsoft.Devices.CameraOperationCompletedEventArgs e)
{
if (e.Succeeded)
{
this.Dispatcher.BeginInvoke(delegate()
{
_canvasHeight = Application.Current.Host.Content.ActualWidth;
_canvasWidth = _canvasHeight * GetCameraAspectRatio();
viewfinderCanvas.Width = _canvasWidth;
viewfinderCanvas.Height = _canvasHeight;
});
}
}
//Failinime andmine ning salvestamine.
private async void cam_CaptureImageAvailable(object sender, Microsoft.Devices.ContentReadyEventArgs e)
{
if (ComboNumber == 1)
{
comboValue = "O";
}
if (ComboNumber == 2)
{
comboValue = "T";
}
if (ComboNumber == 3)
{
comboValue = "S";
}
if (ComboNumber == 4)
{
comboValue = "P";
}
if (ComboNumber == 5)
{
comboValue = "A";
}
if (ComboNumber == 6)
{
comboValue = "M";
}
string fileName = String.Format(FileText + "_" + comboValue + "_" + DateTime.Now.ToString("dd-MM-yyyy_HH-mm-ss") + ".jpg");
try
{
LiveOperationResult operationResult = await this.liveClient.UploadAsync("/me/skydrive", fileName, e.ImageStream, OverwriteOption.Overwrite); //Cannot await 'void'
}
catch (LiveConnectException ex)
{
// e.ImageStream.Close();
// this.infoTextBlock.Text = "Error getting contact info: ";
// this.infoTextBlock.Visibility = Visibility.Visible;
}
finally
{
e.ImageStream.Close();
y++;
Dispatcher.BeginInvoke(delegate()
{
string b = Convert.ToString(y);
loobvalue2.Text = b;
});
}
}
//kaameranupu vajutus.
private void takephoto_Click(object sender, RoutedEventArgs e)
{
if (_cam != null)
{
_cam.CaptureImage();
x++;
string s = x.ToString();
loobvalue.Text = s;
}
}
// Ühenduse Loomine. Session load.
private async void connectButton_Click(object sender, RoutedEventArgs e)
{
bool connected = false;
try
{
var authClient = new LiveAuthClient("RemovedforWeb");
LiveLoginResult result = await authClient.LoginAsync(new string[] { "wl.signin", "wl.skydrive" }); // cannot await 'void'
if (result.Status == LiveConnectSessionStatus.Connected)
{
connected = true;
var connectClient = new LiveConnectClient(result.Session);
var meResult = await connectClient.GetAsync("me");
dynamic meData = meResult.Result; //cannot await 'void'
}
else
{
//btnSignin.Visibility = Visibility.Visible;
}
}
catch (LiveAuthException ex)
{
}
EDIT: I added more code, and commented on problematic places
public async Task Method1 ()
{
}
public async Task<int> Method2 ()
{
}
For the above code, "Method1" does not return any value, whereas "Method2" returns an "int" value.
int i = await Method2(); //this is correct
await Method2(); //this is correct
int i = await Method1(); //this is NOT correct
await Method1(); //this is also correct
For the following line of code
LiveOperationResult operationResult = await this.liveClient.UploadAsync("/me/skydrive", fileName, e.ImageStream, OverwriteOption.Overwrite); //Cannot await 'void'
The "UploadAsync" method does not return any value, that's what it seems if you say "Cannot await 'void'"
Try removing "LiveOperationResult operationResult =" from the line of code and just write -
await this.liveClient.UploadAsync("/me/skydrive", fileName, e.ImageStream, OverwriteOption.Overwrite);
Same for the second line of code-
LiveLoginResult result = await authClient.LoginAsync(new string[] { "wl.signin", "wl.skydrive" }); // cannot await 'void'
Re-Write it as-
await authClient.LoginAsync(new string[] { "wl.signin", "wl.skydrive" }); // cannot await 'void'