how to understand who wanted the result of a method - c#

I have two methods alphaClicked() and betaClicked() and for them to work we need to be connected to a service in the net so I have another method named connect() so in both classes we need to be connected first so we check if we are connected then if we are not then we call connect() method then we get the result of the connection in ActionConnectionResultReceived so if we connected successfully I want to call alphaClicked() if alpha was the one requesting the connect() and call betaClicked() if betaClicked() was the one requesting the connect() method what is the best way to do that?
To summarize this is the issue :
alpha and beta need to connect but connect result doesn't comes back immediately , so we get it via ActionConnectionResultReceived so , how to get who called the connect was it alpha or beta
private void alphaClicked()
{
if(GooglePlayConnection.State == GPConnectionState.STATE_CONNECTED) {
//do something
}
else
{
Connect();
}
}
private void betaClicked()
{
if(GooglePlayConnection.State == GPConnectionState.STATE_CONNECTED) {
//do something else
}
else
{
Connect();
}
}
private void ActionConnectionResultReceived(GooglePlayConnectionResult result)
{
if (result.IsSuccess)
{
Debug.Log("Connected!");
//if alpha requested call alpha if beta requested call beta
//how to do this?
}
else
{
Debug.Log("Cnnection failed with code: " + result.code.ToString());
}
}
private void Connect()
{
GooglePlayConnection.Instance.Connect();
}

Without Async or event handler, and provided you only call one connect per time, you could introduce a variable which stores the last caller:
string gCaller = "";
private void Connect(string caller){
gCaller = caller;
//something else
}
And then use it like this:
private void alphaClicked()
{
if(GooglePlayConnection.State == GPConnectionState.STATE_CONNECTED) {
//do something
}
else
{
Connect("alpha");
}
}
private void betaClicked()
{
if(GooglePlayConnection.State == GPConnectionState.STATE_CONNECTED) {
//do something else
}
else
{
Connect("beta");
}
}
Then when you need the last one who creates the connection, you use the info in gCaller.
private void ActionConnectionResultReceived(GooglePlayConnectionResult result)
{
if (result.IsSuccess)
{
Debug.Log("Connected!");
switch (gCaller){
case "alpha":
alphaClicked();
break;
case "beta":
betaClicked();
break;
default:
break;
}
}
else
{
Debug.Log("Cnnection failed with code: " + result.code.ToString());
}
}
But the best way would be to create async or event handler for Connected events. Take a look on this MSDN article.

Related

Send the progress bar as a parameter to a function in another class that return Task<bool> Type

I want to send a progress bar that is available on my form to a function to display the progress of the operation of that function and finally return true if everything is fine and return false if else
The operation inside the SaveBadCustomerMustStayMasdoodExcelFile function is executed asynchronously so as not to interfere with the execution of other operations.
When the program runs and the compiler calls the line _ProgressBar.Invoke((MethodInvoker)(() => {_ProgressBar.Value = Convert.ToInt32(i);})); Inside the badCustomers.SendToDB(progressBar_BadCustomers) function, there is no feedback and the program seems to be stuck in an infinite loop.
But if the output of the SaveBadCustomerMustStayMasdoodExcelFile function is defined as void, everything works fine.
My code when the system hangs:
In Button:
private void btn_ChoiceBadCustomersFile_Click(object sender, EventArgs e)
{
try
{
DialogResult dialogResult = MessageBox.Show("message", "title",
MessageBoxButtons.YesNo);
if ((dialogResult == DialogResult.Yes))
{
bool result = false;
try
{
result = GetDataFromExcelFile.SaveBadCustomerMustStayMasdoodExcelFile(
progressBar_BadCustomers).Result;
}
catch
{
result = false;
}
if (result)
{
//code...
}
}
}
catch
{
//code...
}
}
Code In GetDataFromExcelFile.SaveBadCustomerMustStayMasdoodExcelFile(...)
public static class GetDataFromExcelFile
{
public async static Task<bool> SaveBadCustomerMustStayMasdoodExcelFile(
DevComponents.DotNetBar.Controls.ProgressBarX progressBar_BadCustomers)
{
try
{
PoomaDbAppEntities DB10 = new PoomaDbAppEntities();
IQueryable<tbl_BadCustomers> dt = null;
MyExcelWorkSpace _excelApp = new MyExcelWorkSpace();
MyExcelWorkSpace.badCustomers badCustomers = new MyExcelWorkSpace
.badCustomers();
string path = badCustomers.select();
if (path != String.Empty)
{
if (badCustomers.Open(path))
{
try
{
await Task.Run(() => { dt = badCustomers
.SendToDB(progressBar_BadCustomers); });
return true;
}
catch
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
catch
{
return false;
}
}
}
And In badCustomers.SendToDB(...) :
public class badCustomers : ExcelFile, IStartWorkWithExcelFile<tbl_BadCustomers>
{
//code
public IQueryable<tbl_BadCustomers> SendToDB(DevComponents.DotNetBar
.Controls.ProgressBarX _ProgressBar)
{
try
{
//code
_ProgressBar.Invoke((MethodInvoker)(() => {
_ProgressBar.Value = Convert.ToInt32(i); }));
}
catch
{
//code
}
}
IQueryable<tbl_BadCustomers> dt = DB10.tbl_BadCustomers.Select(i => i);
return dt;
}
}
If the SaveBadCustomerMustStayMasdoodExcelFile function is defined as below, the program works, but I need to know if an error has occurred or not.
public async static void SaveBadCustomerMustStayMasdoodExcelFile(
DevComponents.DotNetBar.Controls.ProgressBarX progressBar_BadCustomers)
{
//code
}
If the SaveBadCustomerMustStayMasdoodExcelFile function is defined as below, the program works, but I need to know if an error has occurred or not.
public async static void SaveBadCustomerMustStayMasdoodExcelFile(
DevComponents.DotNetBar.Controls.ProgressBarX progressBar_BadCustomers)
{
//code
}
there is no feedback and the program seems to be stuck in an infinite loop.
This is because the code is using Result; full details on my blog.
To solve this, you want to avoid async void (i.e., for SaveBadCustomerMustStayMasdoodExcelFile); async void is intended for event handlers, so you can make btn_ChoiceBadCustomersFile_Click an async void method. Everything else should use await and async Task.
As far as the Progress goes, I echo the recommendations in the comments: IProgress<T> with Progress<T> makes your code cleaner (e.g., no Invoke necessary).

C# Form App - stop execution of all code from a helper method that resides in a helper class

I just learned how to pass arguments into methods, so I'm refactoring my code to make it cleaner. I have created a new "ValidateInput" class which holds a ValidateFinancialsInput method which I pass a string into. It then checks the string to see if it is correct, if it's not I want to show a messageBox, then stop execution of ALL of the code. If i use "return;", it just resumes execution of the Parent method. How do I stop execution of all of the code within the ValidateFinancialsInput method? I tried researching this for a while to no avail. Here is my code:
Class Parent
{
private void button2_Click(object sender, EventArgs e)
{ var CompanyVar = comboBox1.Text;
ValidateInput vi = new ValidateInput();
vi.ValidateFinancialsInput(CompanyVar);
//the rest of my code for the application is here
//the rest ...
//the rest...
}
}
class ValidateInput
{
public void ValidateFinancialsInput(string Co)
{
string[] validCompany = { "BVV", "LWDO" };
if (validCompany.Contains(Co) == false)
{
MessageBox.Show("You have entered an invalid company.");
//what do I put here to stop all code execution?
}
}
}
You should try and use return values state intent to calling methods
Class Parent
{
private void button2_Click(object sender, EventArgs e)
{ var CompanyVar = comboBox1.Text;
ValidateInput vi = new ValidateInput();
if(!vi.ValidateFinancialsInput(CompanyVar))
{
MessageBox.Show("You have entered an invalid company.");
return;
}
//the rest of my code for the application is here
//the rest ...
//the rest...
}
}
class ValidateInput
{
public bool ValidateFinancialsInput(string Co)
{
string[] validCompany = { "BVV", "LWDO" };
if (validCompany.Contains(Co) == false)
{
return false;
}
return true;
}
}
What I'm doing here is returning a true|false value to indicate whether the validation has passed, if it has not passed then I display the MessageBox, else it continues the execution of the "other" code.
Hope this helps
The simplest way is with an exception:
class Parent
{
private void button2_Click(object sender, EventArgs e)
{
try
{
var CompanyVar = comboBox1.Text;
ValidateInput vi = new ValidateInput();
vi.ValidateFinancialsInput(CompanyVar);
//the rest of my code for the application is here
//the rest ...
//the rest...
}
catch (ValidationException ex)
{
MessageBox.Show(ex.Message);
}
}
}
class ValidationException : Exception
{
public ValidationException(string message) : base(message)
{
}
}
class ValidateInput
{
public void ValidateFinancialsInput(string Co)
{
string[] validCompany = { "BVV", "LWDO" };
if (validCompany.Contains(Co) == false)
{
throw new ValidationException("You have entered an invalid company.");
}
}
}
This will stop execution of ValidateFinancialsInput and in button2_Click move execution inside the catch (ValidationException ex) where you can decide what to do with the validation error
You have a class that it's whole purpose is to validate, So you could add a public method IsValidated
You could add much more with the class, for example have a list of all business rules it violates and return them through another method or property.
class ValidateInput
{
public bool IsValidated {get; private set}
public bool ValidateFinancialsInput(string Co)
{
string[] validCompany = { "BVV", "LWDO" };
this.IsValidated = validCompany.Contains(Co)
}
}
This class should only know about the validation process and should do nothing else.
You have a few options. It looks like you have buttons in your program so I would guess this is not a console application. If you want the application to completely stop you can use Application.Exit or check out Environment.Exit https://msdn.microsoft.com/en-us/library/system.environment.exit(v=vs.110).aspx
However, I would suggest using exceptions so you do not terminate your entire program:
try
{
var CompanyVar = comboBox1.Text;
ValidateInput vi = new ValidateInput();
vi.ValidateFinancialsInput(CompanyVar);
//the rest of my code for the application is here
//the rest ...
//the rest...
}
catch (ValidationException ex)
{
MessageBox.Show(ex.Message);
}
}
public void ValidateFinancialsInput(string Co)
{
string[] validCompany = { "BVV", "LWDO" };
if (validCompany.Contains(Co) == false)
{
throw new ValidationException("You have entered an invalid company.");
}
}

C# TcpSockets Do I disconnect the clean/proper way?

So i know there are a lot of articles out there on this topic and i did read a lot of them i would say but for some reason im sure my code is not doing what it is supposed to do.
I want to close a connection between my Server and my Client.
Now on the serverside i start the disconnect with this code
public void shutdown()
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
And on the Client side i have some troubles understanding how i get to the disconnect what i believe is happening is the following: in my async receive callback i should get an error since the server started a shutdown sequence and i have to handle that (right???) so my code for the client looks like this:
ReceiveCallback:
private void ReceiveCallback(IAsyncResult result)
{
int bytesRecieved = 0;
byte[] tempBuff;
//Try to receive But if a Socket error occures disconnect otherwise start Receiving again
try
{
bytesRecieved = _socket.EndReceive(result);
}
catch (SocketException sockEx)
{
Disconnect(sockEx);
return;
}
catch (ObjectDisposedException disposeEx)
{
Disconnect(disposeEx);
return;
}
catch (Exception ex)
{
StartReceive();
return;
}
if (bytesRecieved == 0)
{
StartReceive();
return;
}
tempBuff = new byte[bytesRecieved];
Buffer.BlockCopy(_buffer, 0, tempBuff, 0, bytesRecieved);
StartReceive();
_packHandler.handlePacket(tempBuff);
}
Disconnect:
public void Disconnect()
{
if (!_socket.Connected)
{
return;
}
_socket.BeginDisconnect(false, DisconnectCallback, null);
}
DisconnectCallback
private void DisconnectCallback(IAsyncResult result)
{
_socket.EndDisconnect(result);
_socket.Close();
}
(The Disconnect Method is overloaded so if i get an exception it puts up a messageBox and then also calls Disconnect. Just so i know what happened.)
Where am i wrong and what can i improve uppon ???
I tried the code and it seemed to work but i then looked with netstat if all sockets are closed and the client socket was not. It was in FIN_WAIT_2 which means that it (or the server???) did not yet send the FIN packet right ?
Oh and then i tried it again with this line changed:
if (bytesRecieved == 0)
{
StartReceive();
return;
}
TO
if (bytesRecieved == 0)
{
Disconnect;
return;
}
which then threw an exception on the serverside and on the clientside the client said that the connection was closed by the server ???
EDIT: Even when i have closed both Programs Netstat still shows the port in a WAITING status. what does that tell me ?
Your normal disconnect has a shutdown which will clear the socket so it can disconnect properly but your async style never calls shutdown. I added it in a convenient location below.
public void Disconnect()
{
if (!_socket.Connected)
{
return;
}
_socket.Shutdown(SocketShutdown.Both); // Make sure to do this
_socket.BeginDisconnect(false, DisconnectCallback, null);
}
EDIT:
From the sounds of it you don't have a reason to be using the Async Method? The async methods are so you can send data in a separate execution thread freeing up your thread to do some data processing for instance while that occurs.
I don't see any processing going on so I suggest you change disconnect like this and see if it resolves the problem. Because I don't think you are waiting on the Async methods which will not work out well.
public void Disconnect()
{
if (!_socket.Connected)
{
return;
}
shutdown(); //Your standard disconnect that you showed up top. Scoping might be required.
}
A bit of data on Async can be scrounged up here: http://msdn.microsoft.com/en-us/library/38dxf7kt(v=vs.110).aspx
Important is:
If a server starts a shutdown sequence you DO have to handle it
Both sides have to call shutdown on their socket
You need a way to notice the disconnect (it does not give you an error, or least it didnt for me)
Therefor I created my own class customSocket which inherits from Socket
public class customSocket : Socket
{
#region Properties
private readonly Timer _timer;
private const int _interval = 1000;
private bool Connected
{
get
{
bool part1 = Poll(1000, SelectMode.SelectRead);
bool part2 = (Available == 0);
if (part1 && part2)
return false;
else
return true;
}
}
public bool EventsEnabled
{
set
{
if (value)
{
_timer.Start();
}
else
_timer.Stop();
}
}
#endregion
#region Constructors
public customSocket(AddressFamily addressFamily, SocketType sockType, ProtocolType protocolType)
: base(addressFamily, sockType, protocolType)
{
_timer = new Timer { Interval = _interval };
_timer.Elapsed += TimerTick;
}
public customSocket(SocketInformation sockInfo)
: base(sockInfo)
{
_timer = new Timer { Interval = _interval };
_timer.Elapsed += TimerTick;
}
#endregion
#region Events
public event EventHandler<EventArgs> Socket_disconected;
public void Raise_Socket_disconnected()
{
EventHandler<EventArgs> handler = Socket_disconected;
if (handler != null)
{
handler(this,new EventArgs());
}
}
private void TimerTick(object sender, EventArgs e)
{
if (!Connected)
{
Raise_Socket_disconnected();
}
}
#endregion
}
This version of a socket has an Event for a disconnect.
Now if you create an instance of your socket class you have to connect the handler and set the EventsEnabled true.
This handler then calls the shutdown and your socket does not stay in FIN_WAIT_2

Invalid cross-thread access from XNA GamerService

I am asking the user of my app per the XNA GamerService dialog-box, if he really wants to delete a specific product.
And if he presses yes, this will take action:
private void OnMessageBoxAction(IAsyncResult ar)
{
int? selectedButton = Guide.EndShowMessageBox(ar);
switch (selectedButton)
{
case 0:
WebClient cweight = new WebClient();
cweight.Encoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
cweight.Credentials = new NetworkCredential(op.username, op.userpass);
cweight.DownloadStringCompleted += new DownloadStringCompletedEventHandler(deleted);
cweight.DownloadStringAsync(new Uri("http://mydomain.com"));
break;
case 1:
Debug.WriteLine("1 pressed");
break;
default:
Debug.WriteLine("default pressed");
break;
}
}
and when the download completes, I invoke the login method:
private void deleted(object sender, DownloadStringCompletedEventArgs e)
{
Debug.WriteLine("\n[#] deleted");
if (e.Error != null)
{
Debug.WriteLine("Delete problem");
}
Debug.WriteLine("Delete successful");
login(null, null);
}
later on at login I get the invalid cross-thread access at globalprogress.Visibility = System.Windows.Visibility.Visible; and I am pretty sure, that that error would occur through the whole login method.
Handy class:
public class SmartDispatcher
{
public static void BeginInvoke(Action action)
{
if (Deployment.Current.Dispatcher.CheckAccess()
|| DesignerProperties.IsInDesignTool)
{
action();
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(action);
}
}
}

Is this a safe way to execute threads alternatively?

I would like to run code alternatively, so I could stop execution at any moment. Is this code safe?
static class Program
{
static void Main()
{
var foo = new Foo();
//wait for interaction (this will be GUI app, so eg. btnNext_click)
foo.Continue();
//wait again etc.
foo.Continue();
foo.Continue();
foo.Continue();
foo.Continue();
foo.Continue();
}
}
class Foo
{
public Foo()
{
new Thread(Run).Start();
}
private void Run()
{
Break();
OnRun();
}
protected virtual void OnRun()
{
for (var i = 0; i < 5; i++)
{
Console.WriteLine(i);
Break();
}
//do something else and break;
}
private void Break()
{
lock (this)
{
Monitor.Pulse(this);
Monitor.Wait(this);
}
}
public void Continue()
{
lock (this)
{
Monitor.Pulse(this);
Monitor.Wait(this);
}
}
}
Of course I know, that now the application will never ends, but that's not the point.
I need this, because I would like to present steps in some kind of an algorithm and describe what is going on in particular moment, and making everything in one thread would lead to many complications even when using small amount of loops in the code. For example those lines:
for (var i = 0; i < 5; i++)
{
Console.WriteLine(i);
Break();
}
should be then replaced with:
if (this.i < 5)
{
Console.WriteLine(i++);
}
And that is just a small example of what I want to present. The code will be more complicated than a dummy for loop.
I recommend you check out this blog post about implementing fibers.
Code (In case the site goes down.)
public class Fiber
{
private readonly Stack<IEnumerator> stackFrame = new Stack<IEnumerator>();
private IEnumerator currentRoutine;
public Fiber(IEnumerator entryPoint)
{
this.currentRoutine = entryPoint;
}
public bool Step()
{
if (currentRoutine.MoveNext())
{
var subRoutine = currentRoutine.Current
as IEnumerator;
if (subRoutine != null)
{
stackFrame.Push(currentRoutine);
currentRoutine = subRoutine;
}
}
else if (stackFrame.Count > 0)
{
currentRoutine = stackFrame.Pop();
}
else
{
OnFiberTerminated(
new FiberTerminatedEventArgs(
currentRoutine.Current
)
);
return false;
}
return true;
}
public event EventHandler<FiberTerminatedEventArgs> FiberTerminated;
private void OnFiberTerminated(FiberTerminatedEventArgs e)
{
var handler = FiberTerminated;
if (handler != null)
{
handler(this, e);
}
}
}
public class FiberTerminatedEventArgs : EventArgs
{
private readonly object result;
public FiberTerminatedEventArgs(object result)
{
this.result = result;
}
public object Result
{
get { return this.result; }
}
}
class FiberTest
{
private static IEnumerator Recurse(int n)
{
Console.WriteLine(n);
yield return n;
if (n > 0)
{
yield return Recurse(n - 1);
}
}
static void Main(string[] args)
{
var fiber = new Fiber(Recurse(5));
while (fiber.Step()) ;
}
}
"...this will be GUI app..."
Then you probably do not want and will not have sequential code like above in Main().
I.e. the main GUI thread will not execute a serial code like above, but generally be idle, repainting, etc. or handling the Continue button click.
In that event handler you may better use an Auto|ManualResetEvent to signal the worker to proceed.
In the worker, just wait for the event.
I would suggest that any time one considers using Monitor.Wait(), one should write code so that it would work correctly if the Wait sometimes spontaneously acted as though it received a pulse. Typically, this means one should use the pattern:
lock(monitorObj)
{
while(notYetReady)
Monitor.Wait(monitorObj);
}
For your scenario, I'd suggest doing something like:
lock(monitorObj)
{
turn = [[identifier for this "thread"]];
Monitor.PulseAll(monitorObj);
while(turn != [[identifier for this "thread"]])
Monitor.Wait(monitorObj);
}
It is not possible for turn to change between its being checked whether it's the current thread's turn to proceed and the Monitor.Wait. Thus, if the Wait isn't skipped, the PulseAll is guaranteed to awaken it. Note that the code would work just fine if Wait spontaneously acted as though it received a pulse--it would simply spin around, observe turn wasn't set for the current thread, and go back to waiting.

Categories

Resources