Cannot await 'Void' even when using Task - c#

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'

Related

Pausing / Resuming Screen recording with Windows Graphics Capture API

I am building a screen recording app in C# using Windows Graphics Capture API. I am using this script. I can select monitor and can record it to mp4 file. I am trying to add Pause/Resume functionality.
Here is code of main Window that initiates Recording
try
{
newFile = GetTempFile();
using (var stream = new FileStream(newFile, FileMode.CreateNew).AsRandomAccessStream())
using (_encoder = new Encoder(_device, item))
{
await _encoder.EncodeAsync(
stream,
width, height, bitrate,
frameRate);
}
}
catch (Exception ex)
{
//
}
And here is the main function from Encoder class, which is used above
private async Task EncodeInternalAsync(IRandomAccessStream stream, uint width, uint height, uint bitrateInBps, uint frameRate)
{
if (!_isRecording)
{
_isRecording = true;
_frameGenerator = new CaptureFrameWait(
_device,
_captureItem,
_captureItem.Size);
using (_frameGenerator)
{
var encodingProfile = new MediaEncodingProfile();
encodingProfile.Container.Subtype = "MPEG4";
encodingProfile.Video.Subtype = "H264";
encodingProfile.Video.Width = width;
encodingProfile.Video.Height = height;
encodingProfile.Video.Bitrate = bitrateInBps;
encodingProfile.Video.FrameRate.Numerator = frameRate;
encodingProfile.Video.FrameRate.Denominator = 1;
encodingProfile.Video.PixelAspectRatio.Numerator = 1;
encodingProfile.Video.PixelAspectRatio.Denominator = 1;
var transcode = await _transcoder.PrepareMediaStreamSourceTranscodeAsync(_mediaStreamSource, stream, encodingProfile);
await transcode.TranscodeAsync();
}
}
}
And finally this is the initializer function in CaptureFrameWait class
private void InitializeCapture(SizeInt32 size)
{
_framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
_device,
DirectXPixelFormat.B8G8R8A8UIntNormalized,
1,
size);
_framePool.FrameArrived += OnFrameArrived;
_session = _framePool.CreateCaptureSession(_item);
_session.IsBorderRequired = false;
_session.StartCapture();
}
How can we modify this to pause the recording? I have tried to dispose the _framepool and _session objects on Pause and initialize them again on Resume in CaptureFrameWait class, like shown below. It works fine, but sometimes TranscodeAsync function terminates during pause and ends recording. How can we avoid that?
bool _paused = false;
public void PauseSession(bool status)
{
if (status) {
_paused = true;
_framePool?.Dispose();
_session?.Dispose();
}
else {
InitializeCapture(_size);
_paused = false;
}
}
One solution is to get a deferral. Doc says:
The MediaStreamSource will then wait for you to supply the
MediaStreamSample until you mark the deferral as complete.
So for example, add two private members to the Encoder class and two methods:
private MediaStreamSourceSampleRequestedEventArgs _args;
private MediaStreamSourceSampleRequestDeferral _def;
public bool IsPaused { get; private set; }
public void Pause()
{
IsPaused = true;
}
public void Resume()
{
IsPaused = false;
// complete the request we saved earlier
OnMediaStreamSourceSampleRequested(_mediaStreamSource, _args);
}
And modify OnMediaStreamSourceSampleRequested methods like this (where I've put comments):
private void OnMediaStreamSourceSampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args)
{
if (_isRecording && !_closed)
{
// if paused get a deferral and save the current arguments.
// OnMediaStreamSourceSampleRequested will not be called again until we complete the deferral
if (IsPaused)
{
_def = args.Request.GetDeferral();
_args = args;
return;
}
try
{
using (var frame = _frameGenerator.WaitForNewFrame())
{
if (frame == null)
{
args.Request.Sample = null;
DisposeInternal();
return;
}
var timeStamp = frame.SystemRelativeTime;
var sample = MediaStreamSample.CreateFromDirect3D11Surface(frame.Surface, timeStamp);
args.Request.Sample = sample;
// when called again (manually by us) complete the work
// and reset members
if (_def != null)
{
_def.Complete();
_def = null;
_args = null;
}
}
}
catch (Exception e)
{
...
}
}
else
{
...
}
}
Another solution is to simply freeze the frames timestamp, so add these members:
private TimeSpan _pausedTimestamp;
public bool IsPaused { get; private set; }
public void Pause()
{
IsPaused = true;
}
public void Resume()
{
IsPaused = false;
}
And modify OnMediaStreamSourceSampleRequested methods like this (where I've put comments):
private void OnMediaStreamSourceSampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args)
{
if (_isRecording && !_closed)
{
try
{
using (var frame = _frameGenerator.WaitForNewFrame())
{
if (frame == null)
{
args.Request.Sample = null;
DisposeInternal();
return;
}
// if paused, "freeze" the timestamp
TimeSpan timeStamp;
if (IsPaused)
{
timeStamp = _pausedTimestamp;
}
else
{
timeStamp = frame.SystemRelativeTime;
_pausedTimestamp = timeStamp;
}
var sample = MediaStreamSample.CreateFromDirect3D11Surface(frame.Surface, timeStamp);
args.Request.Sample = sample;
}
}
catch (Exception e)
{
...
}
}
else
{
...
}
}

How to set Timer in winform for executing 10+ command?

I have around 10 commands of Tx,Rx with time interval of 100 millisecond for each. So Basically a TxRx pair should be executed within every 100 milliseconds. unless the stop button is clicked. Where am I getting Wrong?
Form1 btn_Start
set the time Interval to request and receive the message
private void btn_Start_Click(object sender, EventArgs e)
{
Start();
}
private void Start()
{
btn_Start.Enabled = false;
btn_Stop.Enabled = true;
int Interval = 100;
if (CANTimer.Enabled == false)
{
// CAN Timer confinguration
CANTimer.Enabled = true;
CANTimer.Interval = Convert.ToInt32(fCANInterval); //Interval;
CANTimer.Tick += new System.EventHandler(this.CANTimer_Tick);
CANTimer.Start();
}
else if (CANTimer.Enabled && Program_config_num == 0)
{
CANTimer.Stop();
CANTimer.Interval = Convert.ToInt32(fCANInterval); //Interval;
CANTimer.Enabled = true;
CANTimer.Start();
}
}
Form1 CANTimer_Tick
Execute the command to Send and Receive Messages in every 100 milliseconds, till the btn_Stop is clicked
private void CANTimer_Tick(object sender, EventArgs e)
{
ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxCompletionPortThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThread);
int unit_index = 1;
if(IsConnected == false)
{
IsConnected = CANClass.connect();
lbl_Status.Text = "Connected";
}
else
{
Req1_Send = CAN.Send_Req1(unit_index, CANClass); //Sends request for Msg1 to MCU through CANClass
if ((Req1_Send == true) && (Msg1_Received == false))
{
ThreadPool.QueueUserWorkItem(ReadMsg1); //Reads the message and display
}
Req2_Send = CAN.Send_Req2(unit_index, CANClass); //Sends request for Msg2 to MCU through CANClass
if ((Req2_Send == true) && (Msg2_Received == false))
{
ThreadPool.QueueUserWorkItem(ReadMsg2); //Reads the message and display
}
Req3_Send = CAN.Send_Req3(unit_index, CANClass); //Sends request for Msg3 to MCU through CANClass
if ((Req3_Send == true) && (Msg3_Received == false))
{
ThreadPool.QueueUserWorkItem(ReadMsg3); //Reads the message and display
}
............... till the Msg10
}
}
btn_Stop
Stop the connection
private void btn_Stop_Click(object sender, EventArgs e)
{
Stop();
}
private void Stop()
{
btn_Start.Enabled = true;
btn_Stop.Enabled = false;
CanPacket.CanStop();
IsConnected = false;
}
```
The thing with hardware controllers is that (usually) you don't know exactly how long they'll take to fill up the RX Buffer so that you can get the packet response from the TX-RX pair. If you're doing it on a timer tick you're between the terrible risk of buffer underrun (possibly hanging the controller) or wasting time by patting the wait time with margins.
Often it's better to loop in a Task where you perform the IO synchronously (hopefully this involves actual handshaking) for your "10+ Commands" and then get the "100 ms spacing" after all the TX-RX pairs have completed and before the next iteration of the loop.
private async void checkBoxRun_CheckedChanged(object sender, EventArgs e)
{
if (checkBoxRun.Checked)
{
richTextBox.Clear();
await Task.Run(() => loop());
labelIndicator.BackColor = Color.LightGray;
}
}
private async Task loop()
{
do
{
await readCanBusSingle();
if (!checkBoxRun.Checked) return;
// Here's where the spacing of 100 ms or whatever happens.
// I made it longer for test.
await Task.Delay(TimeSpan.FromSeconds(1));
}
while (checkBoxRun.Checked);
}
private async Task readCanBusSingle()
{
string text;
if (_busController.TryConnect())
{
BeginInvoke((MethodInvoker)delegate
{
labelIndicator.BackColor = Color.LightGreen;
richTextBox.SelectionFont = new Font(richTextBox.Font, FontStyle.Bold);
richTextBox.AppendText($"{Environment.NewLine}{DateTime.Now}: REQUEST{Environment.NewLine}");
richTextBox.SelectionFont = new Font(richTextBox.Font, FontStyle.Regular);
});
foreach (RequestID requestID in Enum.GetValues(typeof(RequestID)))
{
var packet = new Packet { RequestID = requestID };
// HARWARE CONTROLLER: Push some bytes into TXQueue
_busController.SendReq(unitIndex: 1, packet: packet);
// HARWARE CONTROLLER: Wait for RXQueue bytes to be present
// Often this means a spin (not an await) until the full
// reapi=onse is available in the MCU.
await Task.Run(() =>
{
while(_busController.Busy)
{
Task.Delay(10).Wait();
}
});
if (packet.MockResponse is uint[] bytes)
{
text = string.Join(" ", bytes.Select(_ => _.ToString("X4")));
}
else
{
text = $"{packet.MockResponse}";
}
BeginInvoke((MethodInvoker)delegate
{
switch (packet.RequestID)
{
case RequestID.REQ1:
richTextBox.SelectionColor = Color.Navy;
break;
case RequestID.REQ2:
richTextBox.SelectionColor = Color.DarkGreen;
break;
case RequestID.REQ3:
richTextBox.SelectionColor = Color.Maroon;
break;
default: throw new InvalidOperationException();
}
richTextBox.AppendText($"{text}{Environment.NewLine}");
richTextBox.ScrollToCaret();
});
}
}
else
{
BeginInvoke((MethodInvoker)delegate
{
labelIndicator.BackColor = Color.LightSalmon;
richTextBox.SelectionColor = Color.Red;
richTextBox.AppendText($"{Environment.NewLine}Connection lost{Environment.NewLine}");
richTextBox.ScrollToCaret();
});
}
}
MOCK
Where:
public enum RequestID { REQ1, REQ2, REQ3 }
public class McuController
{
internal bool TryConnect()
{
switch (Rando.Next(10))
{
case 0:
// The mock controller fails every now and then
return false;
default:
return true;
}
}
internal async void SendReq(int unitIndex, Packet packet)
{
Busy = true;
await packet.SetMockResponse(TimeSpan.FromMilliseconds(Rando.Next(10, 51)));
Busy = false;
}
public static Random Rando { get; } = new Random();
public bool Busy { get; private set; }
}
public class Packet
{
public RequestID RequestID { get; set; }
public int UnitID { get; set; }
// MOCK
public object MockResponse { get; set; }
public async Task SetMockResponse(TimeSpan mockDelay)
{
await Task.Delay(mockDelay);
switch (RequestID)
{
case RequestID.REQ1:
// String
MockResponse =
$"Unit {UnitID}";
break;
case RequestID.REQ2:
// ByteArray
MockResponse =
Enumerable.Range(0, 8)
.Select(_ => (uint)Rando.Next(45000, 55000))
.ToArray();
break;
case RequestID.REQ3:
MockResponse =
mockDelay;
break;
default: throw new InvalidOperationException();
}
}
}

How to use Thread in the button below

When I press the button, decoding a Qrcode works well but I want to do it with a Thread.
I wrote like below but the thread doesn't work.
Does anyone know, how can i fix it?
Thanks.
Here is my code:
private async void button2_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
pictureBox1.Image = Image.FromFile(#"C:\Users...\1.jpg");
MessagingToolkit.QRCode.Codec.QRCodeDecoder decoder = new MessagingToolkit.QRCode.Codec.QRCodeDecoder();
textBox2.Text = decoder.Decode(new QRCodeBitmapImage(pictureBox1.Image as Bitmap));
});
}
This will keep your UI responsive
private async void button2_Click(object sender, EventArgs e)
{
var Result = await Decode("Image Path");
textBox2.Text = Result;
}
private async Task<string> Decode(string PathOfImage)
{
var DecodedText = string.Empty;
var decoder = new MessagingToolkit.QRCode.Codec.QRCodeDecoder();
await Task.Run(() =>
{
DecodedText = decoder.Decode(new QRCodeBitmapImage(Image.FromFile(PathOfImage) as Bitmap));
});
return DecodedText;
}
Update 2 : here is how you can do it in one function :
private async void button2_Click(object sender, EventArgs e)
{
var DecodedText = string.Empty;
var decoder = new MessagingToolkit.QRCode.Codec.QRCodeDecoder();
await Task.Run(() => {
DecodedText = decoder.Decode(new QRCodeBitmapImage(Image.FromFile(PathOfImage) as Bitmap));
});
textBox2.Text = DecodedText;
}
You should update the TextBox after the completion of the Task, at a point where you are back to the UI thread.
private async void button2_Click(object sender, EventArgs e)
{
var bitmap = await Task.Run(() =>
{
return (Bitmap)Image.FromFile(#"C:\Users...\1.jpg");
});
pictureBox1.Image = bitmap;
var result = await Task.Run(() =>
{
var decoder = new MessagingToolkit.QRCode.Codec.QRCodeDecoder();
return decoder.Decode(new QRCodeBitmapImage(bitmap));
});
textBox2.Text = result;
}
Update: The code that updates the PictureBox should be moved out of the Task.Run body too.
Update: The loading of image can block the UI too, so I moved it in a separate Task.
The dispatcher object is used to modify the UI from a thread or a Task
Below how to use a Task
Method 1
bool result ;
Task<bool> task = Task.Run<bool>(async () => await RefreshUIAsync());
str = task.Result;
public async Task<bool> RefreshUIAsync()
{
bool result;
result= await Task.Factory.StartNew(() => RefreshUI());
return result;
}
private string RefreshUI()
{
bool result;
try
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
string ImagePath="";
pictureBox1.Image = Image.FromFile(ImagePath);
.......
});
result=true;
}
catch (Exception ex)
{
result=false;
}
return result;
}
Method 2
RefreshUIAsync().Wait();
public async Task RefreshUIAsync()
{
await Task.Run(() => {
This.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
string ImagePath="";
pictureBox1.Image = Image.FromFile(ImagePath);
.......
});
});
}
And below how to use a Thread
Method 1
myThread = new Thread(() => ThreaRefreshUI());
myThread.Start();
private void ThreaRefreshUI()
{
try
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
string ImagePath="";
pictureBox1.Image = Image.FromFile(ImagePath);
.......
});
}
catch (Exception ex)
{
}
}
Method 2
Thread thread = new Thread(new ThreadStart(ThreaRefreshUI));
thread.Start();
public void ThreaRefreshUI()
{
try
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
string ImagePath="";
pictureBox1.Image = Image.FromFile(ImagePath);
.......
});
}
catch (Exception ex)
{
}
}
Method 3
Thread thread = new Thread(ThreaRefreshUI);
thread.Start();
public void ThreaRefreshUI()
{
try
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
{
string ImagePath="";
pictureBox1.Image = Image.FromFile(ImagePath);
.......
});
}
catch (Exception ex)
{
}
}

UWP sync communication serial device

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);
}
}
}

Call UWP AppService on winform/wpf client

When i call AppService on UWP app, the AppServiceConnectionStatus returns Success.
But, when i call AppService on winform or wpf client, the AppServiceConnectionStatus still return AppServiceUnavailable.
UWP,Winform,WPF,the client code are the same:
private AppServiceConnection appService;
private async void ConnectServer()
{
if (appService == null)
{
appService = new AppServiceConnection();
appService.AppServiceName = "AserSecurityService";
appService.PackageFamilyName = "AserSecurityService_gfeg8w3smza92";
var status = await this.appService.OpenAsync();
if (status != AppServiceConnectionStatus.Success)
{
appService = null;
return;
}
}
}
The service code below:
public sealed class AserSecurityComponentProviderTask : IBackgroundTask
{
private BackgroundTaskDeferral backgroundTaskDeferral;
private AppServiceConnection appServiceconnection;
public void Run(IBackgroundTaskInstance taskInstance)
{
this.backgroundTaskDeferral = taskInstance.GetDeferral();
taskInstance.Canceled += OnTaskCanceled;
var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
appServiceconnection = details.AppServiceConnection;
appServiceconnection.RequestReceived += OnRequestReceived;
}
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
var requestDeferral = args.GetDeferral();
try
{
var message = args.Request.Message;
var result = new ValueSet();
if (message.ContainsKey("HardwareID"))
{
result.Add("HardwareID", GetHardwareID());
}
await args.Request.SendResponseAsync(result);
}
catch (Exception ex)
{
var result = new ValueSet();
result.Add("exception", ex);
await args.Request.SendResponseAsync(result);
}
finally
{
requestDeferral.Complete();
}
}
private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
if (this.backgroundTaskDeferral != null)
{
this.backgroundTaskDeferral.Complete();
}
}
private string GetHardwareID()
{
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.System.Profile.HardwareIdentification"))
{
var token = HardwareIdentification.GetPackageSpecificToken(null);
var hardwareId = token.Id;
var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);
byte[] bytes = new byte[hardwareId.Length];
dataReader.ReadBytes(bytes);
return BitConverter.ToString(bytes).Replace("-", "");
}
throw new Exception("NO API FOR DEVICE ID PRESENT!");
}
}
How can I solve this issue?
or you can download my sample project code zip from
here or otherLink.

Categories

Resources