Let's say we have this code
namespace app.Entities
{
public class school
{
public bool Addschool() { }
}
}
namespace app.layer1
{
public class ManageSchool
{
public bool schoolInfo() {
schoolInfo.addSchool();
}
}
}
namespace app.layer
{
public class schoolAPi
{
public bool GetAndAdd()
{
ManageSchool.schoolInfo();
}
}
}
i want to know which layers and fuctions called AddSchool() method in app.entitied namespace
for exp :
app.layer2.schoolAPi.GetAndAdd >> app.layer1.ManageSchool.schoolInfo >> app.Entities.school.Addschool
Try look at System.Diagnostics.StackTrace and System.Diagnostics.StackFrame classes.
You can create some Tracer class with Trace method to trace each call, but you supposed to put trace in each method to be able to trace it.
Example of Tracer.cs:
using System.Diagnostics;
public class Tracer
{
public static void Trace()
{
StackFrame sf = new StackTrace(true).GetFrame(1);
Console.WriteLine("Called {0} in {1} at line: {2}", sf.GetMethod().ToString(), sf.GetFileName(), sf.GetFileLineNumber());
}
}
Examples of your project:
Entities.cs:
namespace App.Entities
{
public class School
{
public static bool AddSchool()
{
Tracer.Trace();
return true;
}
}
}
LayerOne.cs:
using App.Entities;
namespace App.LayerOne
{
public class ManageSchool
{
public static bool SchoolInfo()
{
Tracer.Trace();
School.AddSchool();
return true;
}
}
}
LayerTwo.cs:
using App.LayerOne;
namespace App.LayerTwo
{
public class SchoolAPI
{
public static bool GetAndAdd()
{
Tracer.Trace();
ManageSchool.SchoolInfo();
return true;
}
}
}
And a Program.cs:
using System;
using App.LayerTwo;
namespace App
{
class Program
{
static void Main(string[] args)
{
Tracer.Trace();
SchoolMethod();
Console.ReadKey();
}
static void SchoolMethod()
{
Tracer.Trace();
SchoolAPI.GetAndAdd();
}
}
}
It will give you some kind of this result:
Also you can put Tracer.Trace() method under bool condition of some global setting and use it only when you need trace:
if (MySettingsClass.TraceEnabled)
Tracer.Trace();
how to send verificationId from SendOtpCodeAsync() to SendCode_Button_Clicked()
Share Project code
IAuth auth;
auth = DependencyService.Get<IAuth>();
private async void SendCode_Button_Clicked(object sender, EventArgs e)
{
bool result = await auth.SendOtpCodeAsync(PhonenumberEntry.Text);
}
android project code
[assembly: Dependency(typeof(AuthDriod))]
namespace TestApp_MiniApps.Droid
{
public class AuthDriod : PhoneAuthProvider.OnVerificationStateChangedCallbacks, IAuth
{
private TaskCompletionSource<bool> _phoneAuthTcs;
public Task<bool> SendOtpCodeAsync(string phonenumber)
{
_phoneAuthTcs = new TaskCompletionSource<bool>();
Java.Lang.Long num = (Java.Lang.Long)60;
PhoneAuthOptions options =
PhoneAuthOptions.NewBuilder(FirebaseAuth.Instance)
.SetPhoneNumber(phonenumber) // Phone number to verify
.SetTimeout(num, TimeUnit.Seconds) // Timeout and unit
.SetActivity(Platform.CurrentActivity) // Activity (for callback binding)
.SetCallbacks(this) // OnVerificationStateChangedCallbacks
.Build();
PhoneAuthProvider.VerifyPhoneNumber(options);
return _phoneAuthTcs.Task;
}
public override void OnVerificationCompleted(PhoneAuthCredential credential)
{
}
public override void OnVerificationFailed(FirebaseException exception)
{
_phoneAuthTcs?.TrySetResult(false);
}
public override void OnCodeSent(string verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken)
{
base.OnCodeSent(verificationId, forceResendingToken);
_phoneAuthTcs?.TrySetResult(true);
}
}//end of class
}
share project interface
namespace TestApp_MiniApps.Views.Xamarin.FireBase
{
public interface IAuth
{
Task<bool> SendOtpCodeAsync(string phonenumber);
}//end of class
}
To summarise what Leo had put in the comments you can check what is returned from your method call.
Change from bool to your own class. For the purpose of this answer I will call it OtpResult.
// The new class definition:
public class OtpResult
{
public bool Success { get; set; }
// Define whatever you like here
public string StringValue { get; set; }
}
public interface IAuth
{
Task<OtpResult> SendOtpCodeAsync(string phonenumber);
}
I have this method:
public static async Task OpenPageAsync(string route)
{
await Shell.Current.GoToAsync(route, true);
}
If the method is called more than once in 5 seconds I would like the second call to be ignored. Has anyone come across a way to deal with this need?
Note that if it helps I do have access to create properities at the App level like this etc.
public partial class App : Application
{
public static int LastTapTime;
public static int TapTime;
In our project, we have created a 'MaxFrequencyUpdater' for exactly that cause.
Only difference: if within 5 seconds a new call comes in, it is delayed and executed after the 5 seconds interval.
namespace Utils
{
public class MaxFrequencyUpdater
{
private readonly WinformsExceptionHandler _exceptionHandler;
private readonly string _name;
private readonly int _millis;
private MethodInvoker _currentMethod;
private DateTime _lastExecuted = DateTime.MinValue;
private readonly object _updaterLockObject = new object();
public MaxFrequencyUpdater(string name, int maxFrequencyInMillis, WinformsExceptionHandler exceptionHandler)
{
_name = name;
_exceptionHandler = exceptionHandler;
_millis = maxFrequencyInMillis;
}
public void Update(MethodInvoker method)
{
lock (_updaterLockObject)
{
_currentMethod = method;
}
Task.Run(HandleWork);
}
private void HandleWork()
{
lock (_updaterLockObject)
{
// No longer bother, someone else handled it already
if (_currentMethod == null) return;
var now = DateTime.Now;
var delay = (int)(_millis - now.Subtract(_lastExecuted).TotalMilliseconds);
// Post-pone if too soon
if (delay > 0)
{
Task.Delay(delay).ContinueWith(HandleWork);
}
else
{
try
{
_currentMethod.Invoke();
}
catch (Exception e)
{
_exceptionHandler.HandleException(e);
}
_lastExecuted = now;
_currentMethod = null;
}
}
}
}
}
usage:
_maxFrequencyUpdater.Update(() =>
{
doSomething();
});
I have a project and one of the main methods is returning null when it is pretty clear to see I have assigned a value to it.
Program.cs:
using System;
namespace Sahara
{
class Program
{
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Title = "Loading Sahara...";
Console.CursorVisible = false;
Sahara.Initialize();
while (true)
{
Console.ReadKey();
}
}
}
}
Sahara.cs:
namespace Sahara
{
class Sahara
{
private static SaharaServer server;
public static void Initialize()
{
server = new SaharaServer();
}
public static SaharaServer GetServer()
{
return server;
}
}
}
SaharaServer:
using Sahara.Core.Config;
using Sahara.Core.Logging;
using Sahara.Core.Server;
using System;
using System.Diagnostics;
namespace Sahara
{
class SaharaServer
{
private readonly ServerStatusUpdater serverStatusUpdater;
private readonly LogManager logManager;
private readonly ServerInformation serverInformation;
private readonly DateTime startedTime;
private readonly ConfigManager configManager;
public SaharaServer()
{
logManager = new LogManager();
serverInformation = new ServerInformation();
foreach (string consoleOutputString in serverInformation.ConsoleLogo)
{
Console.WriteLine(consoleOutputString);
}
logManager.Log("Loading " + serverInformation.ServerName + "...", LogType.Information);
Stopwatch stopwatch = Stopwatch.StartNew();
configManager = new ConfigManager("Extra/Other/config.ini");
startedTime = DateTime.Now;
serverStatusUpdater = new ServerStatusUpdater();
stopwatch.Stop();
logManager.Log("Finished Loading! [" + stopwatch.ElapsedMilliseconds + "ms]", LogType.Warning);
Console.ForegroundColor = ConsoleColor.Black;
}
public LogManager GetLogManager()
{
return logManager;
}
public ServerInformation GetServerInformation()
{
return serverInformation;
}
public DateTime StartedTime
{
get { return startedTime; }
}
public ConfigManager GetConfigManager()
{
return configManager;
}
public void Dispose()
{
try
{
serverStatusUpdater.Dispose();
}
catch (Exception exception)
{
if (logManager != null)
{
logManager.Log("Error in disposing SaharaServer: " + exception.Message, LogType.Error);
logManager.Log(exception.StackTrace, LogType.Error);
}
}
finally
{
Environment.Exit(0);
}
}
}
}
But why is GetServer() in Sahara.cs returning null!!?!?!?!?
You call the ConfigManager constructor from within the SaharaServer constructor, so the constructor has not yet completed to set the server field and thus GetServer will return null.
I write a C# class library and want to use it in vbscript.
Here is my code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PointOfService;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Reflection;
using System.ComponentModel;
namespace IndigoDynamic
{
#region class implements IAsyncResult
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
public class AsyncResult : IAsyncResult
{
object _state;
private bool m_completed;
private System.Threading.ManualResetEvent m_handle;
private Exception m_exception;
public bool IsCompleted
{
get { return m_completed; }
set { m_completed = value; }
}
public System.Threading.WaitHandle AsyncWaitHandle
{
get { return m_handle; }
set { m_handle = (System.Threading.ManualResetEvent)value; }
}
public object AsyncState
{
get
{
if (Exception != null)
{
throw Exception;
}
return _state;
}
internal set
{
_state = value;
}
}
public bool CompletedSynchronously { get { return IsCompleted; } }
internal Exception Exception
{
get { return m_exception; }
set { m_exception = value; }
}
}
#endregion
#region extends CashDrawer
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
public class MyCashDrawer
{
private CashDrawer me;
public delegate void status_callback(int newstatus);
private status_callback myF;
public MyCashDrawer(CashDrawer param)
{
me = param;
me.StatusUpdateEvent += new StatusUpdateEventHandler(this.StatusUpdate);
}
[ComVisible(true)]
public void Claim(int timeout) { me.Claim(timeout); }
[ComVisible(true)]
public void Close() { me.Close(); }
[ComVisible(true)]
public void Open() { me.Open(); }
[ComVisible(true)]
public void OpenDrawer() { me.OpenDrawer(); }
[ComVisible(true)]
public void Release() { me.Release(); }
[ComVisible(true)]
public void Release(int timeout, int freq, int duration, int delay)
{
me.WaitForDrawerClose(timeout, freq, duration, delay);
}
[ComVisible(true)]
public int StatusClosed() { return CashDrawer.StatusClosed; }
[ComVisible(true)]
public int StatusOpen() { return CashDrawer.StatusOpen; }
[ComVisible(true)]
public bool Claimed() { return me.Claimed; }
[ComVisible(true)]
public bool DeviceEnabled() { return me.DeviceEnabled; }
[ComVisible(true)]
public bool DrawerOpened() { return me.DrawerOpened; }
[ComVisible(true)]
public ControlState State() { return me.State; }
[ComVisible(true)]
public void addStatusCallback(status_callback f)
{
myF = f;
}
[ComVisible(true)]
public void removeStatusCallback(status_callback f)
{
if (myF == f)
myF = null;
}
[ComVisible(true)]
private void StatusUpdate(object sender, StatusUpdateEventArgs arg)
{
if (myF != null)
myF(arg.Status);
}
}
#endregion
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
class VirtualManager : ISynchronizeInvoke
{
private readonly object _sync;
// Constructor
public VirtualManager()
{
_sync = new object();
}
#region implements methods of ISynchronizeInvoke
public IAsyncResult BeginInvoke(Delegate method, object[] args) {
AsyncResult result = new AsyncResult();
System.Threading.ThreadPool.QueueUserWorkItem(delegate {
result.AsyncWaitHandle = new System.Threading.ManualResetEvent(false);
try {
result.AsyncState = Invoke(method, args);
} catch (Exception exception) {
result.Exception = exception;
}
result.IsCompleted = true;
});
return result;
}
public object EndInvoke(IAsyncResult result) {
if (!result.IsCompleted) {
result.AsyncWaitHandle.WaitOne();
}
return result.AsyncState;
}
public object Invoke(Delegate method, object[] args) {
lock (_sync) {
return method.DynamicInvoke(args);
}
}
public bool InvokeRequired {
get { return true; }
}
#endregion
[ComVisible(true)]
public MyCashDrawer getCashDrawer()
{
PosExplorer posExplorer = new PosExplorer(this);
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return new MyCashDrawer(cd);
}
}
[ComVisible(true)]
public MyCashDrawer getCashDrawer(String name)
{
PosExplorer posExplorer = new PosExplorer(this);
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer, name);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return new MyCashDrawer(cd);
}
}
[ComRegisterFunction()]
public static void RegisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
RegistryKey ctrl = k.CreateSubKey("Control");
ctrl.Close();
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
inprocServer32.Close();
k.Close();
}
[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
if (k == null)
{
return;
}
k.DeleteSubKey("Control", false);
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.DeleteSubKey("CodeBase", false);
inprocServer32.Close();
k.Close();
}
}
}
After building, I use RegAsm but it threw Warning No types are registered.
Then I write a sample code in vbs but it says ActiveX can not create Object.
Sub main
set objTest = CreateObject("IndigoDynamic.VirtualManager")
end sub
call main
Somebody said that I have to check AssemblyInfo.cs and make sure I have
[assembly: ComVisible(true)]
Of course I have, but problem is still not solved.
Can anybody tell me a solution?
I change my code like that. More simple, no threading, no interface, all is public.
But it still doesn't work.
Please, I really need help.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PointOfService;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Reflection;
using System.ComponentModel;
namespace IndigoDynamic
{
[ProgId("IndigoDynamic.VirtualManager")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
public class VirtualManager
{
public VirtualManager()
{
}
[ComVisible(true)]
public CashDrawer getCashDrawer()
{
PosExplorer posExplorer = new PosExplorer();
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return cd;
}
}
[ComVisible(true)]
public CashDrawer getCashDrawer(String name)
{
PosExplorer posExplorer = new PosExplorer();
DeviceInfo deviceInfo = posExplorer.GetDevice(DeviceType.CashDrawer, name);
if (deviceInfo == null)
{
//<report failure >
return null;
}
else
{
CashDrawer cd = posExplorer.CreateInstance(deviceInfo) as CashDrawer;
return cd;
}
}
[ComRegisterFunction()]
public static void RegisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
RegistryKey ctrl = k.CreateSubKey("Control");
ctrl.Close();
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
inprocServer32.Close();
k.Close();
}
[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
StringBuilder sb = new StringBuilder(key);
sb.Replace(#"HKEY_CLASSES_ROOT\", "");
RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
if (k == null)
{
return;
}
k.DeleteSubKey("Control", false);
RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
inprocServer32.DeleteSubKey("CodeBase", false);
inprocServer32.Close();
k.Close();
}
}
}
You are unfortunately very far removed from a workable solution. The warning is accurate, none of the classes you made [ComVisible] at creatable by a COM client. MyCashDrawer is missing the required default constructor, a COM client app cannot pass arguments to a constructor. VirtualManager isn't public and derives from an interface that's not [ComVisible]
The code is also missing the required implementations for interfaces that makes an ActiveX component work on a ActiveX host window, like IOleObject, IOleInPlaceObject, IOleInplaceActiveObject, IOleWindow, IViewObject, etcetera. Furthermore, you are exposing implementation details that an ActiveX object can't take care of, the threading model in COM is very different from the one in .NET.
You are going to need a seriously different approach. Consider deriving the visible object from System.Windows.Forms.Control, it takes care of the minimum ActiveX interface implementation requirements. And make threading your problem, don't leave it up to the client to sort it out.
The regasm warning isn't the problem.
Maybe it's beacause VirtualManager class isn't public. Try to expose your class as public.