My app uses internet, so I would like to check, if there is internet connection, and if not - show error.
I have implemented class as shown in this site:
public class InternetConnectionChangedEventArgs : EventArgs
{
public InternetConnectionChangedEventArgs(bool isConnected)
{
this.isConnected = isConnected;
}
private bool isConnected;
public bool IsConnected
{
get { return isConnected; }
}
}
public static class Network
{
public static event EventHandler<InternetConnectionChangedEventArgs>
InternetConnectionChanged;
static Network()
{
NetworkInformation.NetworkStatusChanged += (s) =>
{
if (InternetConnectionChanged != null)
{
var arg = new InternetConnectionChangedEventArgs(IsConnected);
InternetConnectionChanged(null, arg);
}
};
}
public static bool IsConnected
{
get
{
var profile = NetworkInformation.GetInternetConnectionProfile();
var isConnected = (profile != null
&& profile.GetNetworkConnectivityLevel() ==
NetworkConnectivityLevel.InternetAccess);
return isConnected;
}
}
}
But using this approach I have to duplicate my code:
if(Network.IsConnected)
{
//do stuff with internet
}
else
//show error message
Network.InternetConnectionChanged += async (s, args) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
if (args.IsConnected)
{
//do the same stuff with internet
}
else
{
//show the same error message
}
});
};
Because InternetConnectionChanged event launches only if internet connection changes, but I also need to now, if there is internet connection at the beginning. Is there a way to that without duplicating code and not writing each code as separate method?
Just encapsulate your logic in its own method, something like this:
private void DoStuffDependingOnConnection(bool isConnected)
{
if (isConnected)
{
//...
}
else /* ... */
}
Then when your program launches execute
DoStuffDependingOnConnection(Network.IsConnected);
And your event handler will look like this:
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
async () => DoStuffDependingOnConnection(args.IsConnected));
Related
In my web socket wcf service I'm using timer elapsed event to do some logic on my object and after that send information to client (by callback object). I also track callback closed event to clean all object that I'm using in timer elapsed event handler. The problem that i occured is that, when I'm trying to dispose my object i get errors that is still working and to prevent that i try to use lock in both code (timer elapsed event and closed channel event) but it not working correctly (i'm still getting errors that i'm calling method on my object that is no allowed for this moment - this mean that timer elapsed and also call it in the same time).
Is WCF do something special which causes to lock don't work as I expected ?
Here is some of my code:
[ServiceContract(CallbackContract = typeof(IWebSocketsCallback))]
public interface IWebSockets
{
[OperationContract(IsOneWay = true, Action = "*")]
void Start(Message msg);
}
[ServiceContract]
public interface IWebSocketsCallback
{
[OperationContract(IsOneWay = true, Action = "*")]
void SendToClient(Message msg);
}
public class WebSockets : IWebSockets
{
private IWebSocketsCallback callback;
private bool handlePIChanges = false;
private PIDataPipe pipe;
private PIEventsProducer piEventsProducer;
private Timer timer;
private readonly object timerLock = new object();
private readonly object pipeLock = new object();
private bool isPipeClosed = false;
public WebSockets()
{
callback = OperationContext.Current.GetCallbackChannel<IWebSocketsCallback>();
((IChannel)callback).Closed += WebSockets_Closed;
}
public void Start(Message msg)
{
// some custom logic that i ommited ...
timer = CreateTimer();
timer.Elapsed += (sender, e) => PIQueryingCallback(pipe, timer);
}
private void WebSockets_Closed(object sender, EventArgs e)
{
lock (timerLock)
{
handlePIChanges = false;
if (timer != null)
{
timer.Stop();
timer.Dispose();
piEventsProducer.Clear();
}
}
lock (pipeLock)
{
if (pipe != null)
{
pipe.RemoveSignups(pipe.AsReadOnly()); // this cause error, because GetObserverEvents not stopped working
pipe.Close();
isPipeClosed = true;
}
}
}
private void PIQueryingCallback(PIDataPipe pipe, Timer myTimer)
{
bool moreIndicator;
AFErrors<PIPoint> errors;
lock (pipeLock)
{
do
{
if (handlePIChanges && !isPipeClosed)
{
try
{
errors = pipe.GetObserverEvents(2000, out moreIndicator); // this method calls make block for other call on this object untill it return results
}
catch (Exception e)
{
moreIndicator = false;
continue;
}
}
else
{
moreIndicator = false;
}
}
while (moreIndicator);
}
if (handlePIChanges)
{
lock (timerLock)
{
if (handlePIChanges)
{
myTimer.Start();
}
}
}
}
// this method is called after GetObserveEventsCompleted
private void HandlePIDataEventProducerChanges(string msg)
{
if (handlePIChanges && !isPipeClosed)
{
if (((IChannel)callback).State == CommunicationState.Opened)
{
try
{
callback?.SendPIDataChangesToClient(CreateMessage(msg));
}
catch (Exception ex)
{
}
}
}
}
}
My code:
abstract class StateMachine {
protected string State { get; private set; }
protected abstract void OnWorking();
protected abstract void OnPrepare();
protected abstract void OnCancel();
public bool Prepare() {
if(State != null) {
return false;
}
State = "Preparing";
OnPrepare();
State = "Prepared";
return true;
}
public bool Start() {
if(State != "Prepared") {
return false;
}
State = "Working";
OnWorking();
State = "Done";
return true;
}
public bool Cancel() {
if(State != "Working" || State == "Done") {
return false;
}
OnCancel();
State = "Canceled";
return true;
}
}
class Downloader : StateMachine {
protected override void OnPrepare() {
Console.WriteLine("I am preparing.");
Thread.Sleep(1000);
}
protected override void OnWorking() {
Console.WriteLine("I am working.");
Thread.Sleep(1000);
}
protected override void OnCancel() {
Console.WriteLine("Let's cancel the operation!");
}
}
class Program {
static void Main(string[] args) {
Downloader downloader = new Downloader();
Parallel.Invoke(() => {
downloader.Prepare();
downloader.Start();
}, () => {
// Cancel while working
Thread.Sleep(1500);
downloader.Cancel();
});
}
}
The output would be:
I am preparing.
I am working.
Let's cancel the operation!
Now I am building the StateMachine class and it works very well. It allows subclasses to not care about the current states at all, which is awesome because handling states of a process is a huge pain in the head.
The problem is though, nothing can't stop the subclass (Downloader) from calling those protected methods in the base class (StateMachine) by itself. For example, a subclass can have something like:
protected override void OnWorking(){
Console.WriteLine("I am working.");
Thread.Sleep(1000);
OnCancel();
OnPrepare();
}
Then the output would be:
I am preparing.
I am working.
Let's cancel the operation!
I am preparing.
Let's cancel the operation!
Which is not expected from the StateMachine's point of view.
So I am trying to prevent the subclass from calling protected methods. But I feel like I am doing a weird thing. I don't think C# OOP concepts would allow this behavior.
I don't mean to make these protected methods invisible from the subclass though. I'm more about throwing exceptions if subclasses do that. Maybe I need to add extra logic in the base class the handle this. But that might makes the code messy.
What would you do in this situation? I mean, what might be the elegant way to solve this?
You can define them as delegates and make them private, and set them with abstract helper methods as follow:
static void Main()
{
Downloader downloader = new Downloader();
Parallel.Invoke(() =>
{
downloader.Prepare();
downloader.Start();
}, () =>
{
// Cancel while working
Thread.Sleep(1500);
downloader.Cancel();
});
}
abstract class StateMachine
{
protected string State { get; private set; }
private Action OnWorking;
private Action OnPrepare;
private Action OnCancel;
// Helper methods to be implemented in subclass
protected abstract Action DefineWorkingAction();
protected abstract Action DefinePrepareAction();
protected abstract Action DefineCancelAction();
protected StateMachine()
{
this.OnWorking = DefineWorkingAction();
this.OnPrepare = DefinePrepareAction();
this.OnCancel = DefineCancelAction();
}
public bool Prepare()
{
if (State != null)
{
return false;
}
State = "Preparing";
OnPrepare();
State = "Prepared";
return true;
}
public bool Start()
{
if (State != "Prepared")
{
return false;
}
State = "Working";
OnWorking();
State = "Done";
return true;
}
public bool Cancel()
{
if (State != "Working" || State == "Done")
{
return false;
}
OnCancel();
State = "Canceled";
return true;
}
}
class Downloader : StateMachine
{
protected override Action DefineWorkingAction()
{
return () =>
{
Console.WriteLine("I am working.");
Thread.Sleep(1000);
};
}
protected override Action DefinePrepareAction()
{
return () =>
{
Console.WriteLine("I am preparing.");
Thread.Sleep(1000);
};
}
protected override Action DefineCancelAction()
{
return () =>
{
Console.WriteLine("Let's cancel the operation!");
};
}
}
Now subclasses cannot call them anymore.
I trying to allow people to write to NFC tags using my app, so that my app gets launched with a custom parameter. I want to be able to reprogram NFC tags which already have data on them.
I am using the following code but the problem is, that WP always recognizes the action which is already on the NFC tag and interrupts because it wants to launch the NFC tag action which was written anytime before.
How can I tell the OS to stop triggering the action of the tag so that I can immediately rewrite it?
public enum NfcHelperState
{
Initializing,
Waiting,
Ready,
Writing,
Finished,
Error,
NoDeviceFound
}
public class NfcHelper
{
private NfcHelperState _state = NfcHelperState.Initializing;
public NfcHelperState State
{
get { return _state; }
}
private ProximityDevice _nfcDevice;
private long _subscriptionId;
public NfcHelper()
{
Init();
}
public void Init()
{
UpdateState();
_nfcDevice = ProximityDevice.GetDefault();
if (_nfcDevice == null)
{
UpdateState(NfcHelperState.NoDeviceFound);
return;
}
UpdateState(NfcHelperState.Waiting);
}
private void UpdateState(NfcHelperState? state = null)
{
if (state.HasValue)
{
_state = state.Value;
}
if (OnStatusMessageChanged != null)
{
OnStatusMessageChanged(this, _state);
}
}
public void WriteToTag()
{
UpdateState(NfcHelperState.Ready);
_subscriptionId = _nfcDevice.SubscribeForMessage("WriteableTag", WriteableTagDetected);
}
private void WriteableTagDetected(ProximityDevice sender, ProximityMessage message)
{
UpdateState(NfcHelperState.Writing);
try
{
var str = "action=my_custom_action";
str += "\tWindowsPhone\t";
str += CurrentApp.AppId;
_nfcDevice.PublishBinaryMessage("LaunchApp:WriteTag", GetBufferFromString(str),
WriteToTagComplete);
}
catch (Exception e)
{
UpdateState(NfcHelperState.Error);
StopWaitingForTag();
}
}
private void WriteToTagComplete(ProximityDevice sender, long messageId)
{
sender.StopPublishingMessage(messageId);
UpdateState(NfcHelperState.Finished);
StopWaitingForTag();
}
private void StopWaitingForTag()
{
_nfcDevice.StopSubscribingForMessage(_subscriptionId);
}
private static IBuffer GetBufferFromString(string str)
{
using (var dw = new DataWriter())
{
dw.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;
dw.WriteString(str);
return dw.DetachBuffer();
}
}
public delegate void NfcStatusMessageChangedHandler(object myObject, NfcHelperState newState);
public event NfcStatusMessageChangedHandler OnStatusMessageChanged;
}
WriteToTag is called when a button in my app is tapped and the app waits for a writable tag. If a writable tag is recognized, WriteableTagDetected gets called and immediately starts the writing process. However, this is interrupted by the WP dialog which asks whether to perform the NFC action or not. After writing, WriteToTagComplete should be called, where StopWaitingForTag gets called and ends the write process.
I hope you guys can help me :)
Turns out I thought the wrong way. I didn't need to wait for a tag to arrive in order to rewrite it. In fact, there's no need to do _nfcDevice.SubscribeForMessage("WriteableTag", WriteableTagDetected); before writing. Just start using PublishBinaryMessage and it will write to the tag once it arrives at the device.
My final code looks like the following:
public enum NfcHelperState
{
Initializing,
Ready,
WaitingForWriting,
FinishedWriting,
ErrorWriting,
NoDeviceFound
}
public class NfcHelper
{
private NfcHelperState _state = NfcHelperState.Initializing;
public NfcHelperState State
{
get { return _state; }
}
private ProximityDevice _nfcDevice;
private long? _writingMessageId;
public NfcHelper()
{
Init();
}
public void Init()
{
UpdateState();
_nfcDevice = ProximityDevice.GetDefault();
if (_nfcDevice == null)
{
UpdateState(NfcHelperState.NoDeviceFound);
return;
}
UpdateState(NfcHelperState.Ready);
}
private void UpdateState(NfcHelperState? state = null)
{
if (state.HasValue)
{
_state = state.Value;
}
if (OnStatusMessageChanged != null)
{
OnStatusMessageChanged(this, _state);
}
}
public void WriteToTag()
{
StopWritingMessage();
UpdateState(NfcHelperState.WaitingForWriting);
try
{
var str = new StringBuilder();
str.Append("action=my_custom_action");
str.Append("\tWindowsPhone\t{");
str.Append(CurrentApp.AppId);
str.Append("}");
_writingMessageId = _nfcDevice.PublishBinaryMessage("LaunchApp:WriteTag", GetBufferFromString(str.ToString()),
WriteToTagComplete);
}
catch
{
UpdateState(NfcHelperState.ErrorWriting);
StopWritingMessage();
}
}
private void WriteToTagComplete(ProximityDevice sender, long messageId)
{
UpdateState(NfcHelperState.FinishedWriting);
StopWritingMessage();
}
private void StopWritingMessage()
{
if (_writingMessageId.HasValue)
{
_nfcDevice.StopPublishingMessage(_writingMessageId.Value);
_writingMessageId = null;
}
}
private static IBuffer GetBufferFromString(string str)
{
using (var dw = new DataWriter())
{
dw.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE;
dw.WriteString(str);
return dw.DetachBuffer();
}
}
public delegate void NfcStatusMessageChangedHandler(object myObject, NfcHelperState newState);
public event NfcStatusMessageChangedHandler OnStatusMessageChanged;
}
My son is writing a simple RPG game that has a number of non-player characters (aka NPC's). Each NPC has an associated "script" that controls its behaviour. We were going to use a mini custom script language to write these behaviours but I'm now wondering if this would be better done in C#5/Async.
Taking a really simple example, suppose one of the NPC's just walks between two points I'm thinking it would be nice to write something like this:
while (true)
{
await WalkTo(100,100);
await WalkTo(200,200);
}
The WalkTo method would be an async method that handles everything to do with walking between the two points and does this over a number of frames from the game loop. It's not a blocking method that can be off-loaded to a background thread.
And this is where I'm stuck... I haven't been able to find any examples using async/await in this manner, but it seems it would be perfect for it.
Ideas?
Here's some very rough pseudo code for what I'd like to do:
class NpcBase
{
// Called from game loop
public void onUpdate(double elapsedTime)
{
// Move the NPC
.
.
.
// Arrived at destination?
if (Arrived)
{
// How do I trigger that the task is finished?
_currentTask.MarkComplete();
}
}
// Async method called by NPC "script"
public async Task WalkTo(int x, int y)
{
// Store new target location
// return a task object that will be "triggered" when the walk is finished
_currentTask = <something??>
return _currentTask;
}
Task _currentTask;
}
Okay, it sounds like one option would be to have a TaskCompletionSource for each frame of the game. You can then await the Task from WalkTo, and set the result in OnUpdate:
private TaskCompletionSource<double> currentFrameSource;
// Called from game loop
public void OnUpdate(double elapsedTime)
{
...
var previousFrameSource = currentFrameSource;
currentFrameSource = new TaskCompletionSource<double>();
// This will trigger all the continuations...
previousFrameSource.SetResult(elapsedTime);
}
// Async method called by NPC "script"
public async Task WalkTo(int x, int y)
{
// Store new target location
while (/* we're not there yet */)
{
double currentTime = await currentFrameSource.Task;
// Move
}
}
I'm not sure how efficient this will be, admittedly... but it should work.
I think I've figured it out in a simple test program
Firstly, I've got a base class for the NPC's like this:
EDIT: Updated NpcBase to use TaskCompletionSource:
public class NpcBase
{
// Derived classes to call this when starting an async operation
public Task BeginTask()
{
// Task already running?
if (_tcs!= null)
{
throw new InvalidOperationException("busy");
}
_tcs = new TaskCompletionSource<int>();
return _tcs.Task;
}
TaskCompletionSource<int> _tcs;
// Derived class calls this when async operation complete
public void EndTask()
{
if (_tcs != null)
{
var temp = _tcs;
_tcs = null;
temp.SetResult(0);
}
}
// Is this NPC currently busy?
public bool IsBusy
{
get
{
return _tcs != null;
}
}
}
For reference, here's the old version of NpcBase with custom IAsyncResult implementation instead of TaskCompletionSource:
// DONT USE THIS, OLD VERSION FOR REFERENCE ONLY
public class NpcBase
{
// Derived classes to call this when starting an async operation
public Task BeginTask()
{
// Task already running?
if (_result != null)
{
throw new InvalidOperationException("busy");
}
// Create the async Task
return Task.Factory.FromAsync(
// begin method
(ac, o) =>
{
return _result = new Result(ac, o);
},
// End method
(r) =>
{
},
// State object
null
);
}
// Derived class calls this when async operation complete
public void EndTask()
{
if (_result != null)
{
var temp = _result;
_result = null;
temp.Finish();
}
}
// Is this NPC currently busy?
public bool IsBusy
{
get
{
return _result != null;
}
}
// Result object for the current task
private Result _result;
// Simple AsyncResult class that stores the callback and the state object
class Result : IAsyncResult
{
public Result(AsyncCallback callback, object AsyncState)
{
_callback = callback;
_state = AsyncState;
}
private AsyncCallback _callback;
private object _state;
public object AsyncState
{
get { return _state; ; }
}
public System.Threading.WaitHandle AsyncWaitHandle
{
get { throw new NotImplementedException(); }
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return _finished; }
}
public void Finish()
{
_finished = true;
if (_callback != null)
_callback(this);
}
bool _finished;
}
}
Next, I've got a simple "NPC" that moves in one dimension. When a moveTo operation starts it calls BeginTask in the NpcBase. When arrived at the destination, it calls EndTask().
public class NpcTest : NpcBase
{
public NpcTest()
{
_position = 0;
_target = 0;
}
// Async operation to count
public Task MoveTo(int newPosition)
{
// Store new target
_target = newPosition;
return BeginTask();
}
public int Position
{
get
{
return _position;
}
}
public void onFrame()
{
if (_position == _target)
{
EndTask();
}
else if (_position < _target)
{
_position++;
}
else
{
_position--;
}
}
private int _position;
private int _target;
}
And finally, a simple WinForms app to drive it. It consists of a button and two labels. Clicking the button starts both NPC and their position is displayed on the labels.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void onButtonClick(object sender, EventArgs e)
{
RunNpc1();
RunNpc2();
}
public async void RunNpc1()
{
while (true)
{
await _npc1.MoveTo(20);
await _npc1.MoveTo(10);
}
}
public async void RunNpc2()
{
while (true)
{
await _npc2.MoveTo(80);
await _npc2.MoveTo(70);
}
}
NpcTest _npc1 = new NpcTest();
NpcTest _npc2 = new NpcTest();
private void timer1_Tick(object sender, EventArgs e)
{
_npc1.onFrame();
_npc2.onFrame();
label1.Text = _npc1.Position.ToString();
label2.Text = _npc2.Position.ToString();
}
}
And it works, all seems to be running on the main UI thread... which is what I wanted.
Of course it needs to be fixed to handle cancelling of operations, exceptions etc... but the basic idea is there.
All the examples I have seen using SynchronisationContext.Post have been used in the same class. What I have is the UI thread passing some by-ref arguments to a threadwrapper class, updating the arguments and then I want it to update some labels etc on the UIThread.
internal class ConnThreadWrapper
{
....
public event EventHandler<MyEventArgs<String, Boolean>> updateConnStatus =
delegate { };
public void updateUIThread(string conn, bool connected)
{
uiContext.Post(new SendOrPostCallback((o) =>
{
updateConnStatus(this,
new MyEventArgs<String, Boolean>(conn,
connected));
}),
null);
}
}
//on ui thread
public void updateConnStatus(object sender, MyEventArgs<String, Boolean> e)
{
switch (e.val1)
{
case "CADS" :
if (e.val2 == true)
{
}
The Event seems to fire without any errors but nothing is ever received on the uiThread - i'm not sure if my signature for the sub updateConnStatus is correct or if it works like this. I obviously want the event to handled on the uithread and update the labels from that sub.
In a previous vb.net project I used to reference the form directly on the thread and used a delegate to invoke a callback but apparently this was a bad design as I was mixing application layers. I wanted to use the sync context as it was meant to be thread safe but most of the examples i've seen have used invoke.
Any ideas what I'm missing? Thanks
I wrote this helper class which works for me. Prior to using this class call InitializeUiContext() on UI thread somewhere on application start.
public static class UiScheduler
{
private static TaskScheduler _scheduler;
private static readonly ConcurrentQueue<Action> OldActions =
new ConcurrentQueue<Action>();
public static void InitializeUiContext()
{
_scheduler = TaskScheduler.FromCurrentSynchronizationContext();
}
private static void ExecuteOld()
{
if(_scheduler != null)
{
while(OldActions.Count > 0)
{
Action a;
if(OldActions.TryDequeue(out a))
{
UiExecute(_scheduler, a);
}
}
}
}
private static void UiExecute(TaskScheduler scheduler,
Action a,
bool wait = false)
{
//1 is usually UI thread, dunno how to check this better:
if (Thread.CurrentThread.ManagedThreadId == 1)
{
a();
}
else
{
Task t = Task.Factory.StartNew(a,
CancellationToken.None,
TaskCreationOptions.LongRunning,
scheduler);
if (wait) t.Wait();
}
}
public static void UiExecute(Action a, bool wait = false)
{
if (a != null)
{
if (_scheduler != null)
{
ExecuteOld();
UiExecute(_scheduler, a, wait);
}
else
{
OldActions.Enqueue(a);
}
}
}
}
In the end I ditched the ThreadWrapper and trying to marshal the event to the UI Thread and used a Task instead, in fact I think I can use task to do most of the stuff in this project so happy days.
Task<bool> t1 = new Task<bool>(() => testBB(ref _bbws_wrapper));
t1.Start();
Task cwt1 = t1.ContinueWith(task => { if (t1.Result == true) { this.ssi_bb_conn.BackColor = Color.Green;} else { this.ssi_bb_conn.BackColor = Color.Red; } }, TaskScheduler.FromCurrentSynchronizationContext());
.....
private static bool testBB(ref BBWebserviceWrapper _bbwsw)
{
try
{
//test the connections
if (_bbwsw.initialize_v1() == true)
{
if (_bbwsw.loginUser("XXXXXXXX", "XXXXXXXXX") == true)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
catch
{
return false;
}
}