Revit Synchronization event - api

Starting with this...
https://github.com/jeremytammik/RevitLookup/blob/master/CS/EventTrack/Events/ApplicationEvents.cs
I'm trying to add an event listener for a synchronization event. the code below throws an error stating that the m_app is null. Can i not subscribe to this event while Revit is starting up?
I was able to do this before with application.ViewActivated += ..... Im wondering if this has something to do with DB vs UI driven events and when they are allowed to be subscribed to? I just don't know.
namespace RevitModelHealth
{
public class checkHealth : IExternalApplication
{
// Document doc;
static public Autodesk.Revit.ApplicationServices.Application m_app = null;
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
return Result.Succeeded;
}
void m_app_DocumentSavingToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizingWithCentralEventArgs e)
{
MessageBox.Show("asd","asd");
}
}
}
Here is updated code reflecting my response to the first answer. The message box opens when the document is loaded. No errors are thrown when I try to initialize the synchronization event handlers, however, neither of the message boxes open before or after a synchronization event.
public class checkHealth : IExternalApplication
{
// Document doc;
static public Autodesk.Revit.ApplicationServices.Application m_app;
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
application.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(app_DocOpened);
return Result.Succeeded;
}
public void app_DocOpened(object sender, DocumentOpenedEventArgs args)
{
MessageBox.Show("asd","asd");
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
m_app.DocumentSynchronizedWithCentral += new EventHandler<Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs>(m_app_DocumentSavedToCentral);
}
void m_app_DocumentSavingToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizingWithCentralEventArgs e)
{
MessageBox.Show("sync", "sync");
}
void m_app_DocumentSavedToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs e)
{
MessageBox.Show("Doone", "Done");
}
}
this worked.... Thanks largely in part to the SDK sample project EventsMonitor
namespace RevitModelHealth
{
public class checkHealth : IExternalApplication
{
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
application.ControlledApplication.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(app_syncStart);
application.ControlledApplication.DocumentSynchronizedWithCentral += new EventHandler<DocumentSynchronizedWithCentralEventArgs>(app_syncOver);
return Result.Succeeded;
}
public void app_syncStart(object o ,DocumentSynchronizingWithCentralEventArgs args)
{
MessageBox.Show("","Stasrting");
}
public void app_syncOver(object o,DocumentSynchronizedWithCentralEventArgs args)
{
MessageBox.Show("", "Over");
}
}
}

Try
application.ControlledApplication.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral)
in your OnStartup() method.
The call is failing because instance member m_app is initialized to null.
The UIApplication.ControlledApplication object that raises the DocumentSynchronizingWithCentralEventArgs is being accessible from the parameter to OnStartup.

You can try this:
public void app_DocOpened(object sender, DocumentOpenedEventArgs args)
{
MessageBox.Show("asd","asd");
Autodesk.Revit.ApplicationServices.Application m_app = args.Document.Application;
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
m_app.DocumentSynchronizedWithCentral += new EventHandler<Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs>(m_app_DocumentSavedToCentral);
}

Related

AsyncAutoResetEvent not working in WCF async method

I created a WCF service using Visual Studio 2017 Community version (employing TAP). I used the AsyncAutoResetEvent from the Microsoft.VisualStudio.Threading reference but it seems that this waithandle is not getting signalled after calling the Set function. The service is hosted in a console application. The traces generated by the NonBlockingConsole.WriteLine display properly however.
server:
AsyncAutoResetEvent aare = new AsyncAutoResetEvent(false);
public async Task<string> TestfuncAsync()
{
string strRet = "finished";
NonBlockingConsole.WriteLine("before autoresetevent");
await aare.WaitAsync();
NonBlockingConsole.WriteLine("after autoresetevent"); //is not traced even if asyncautoresetevent is set
return strRet;
}
void SetEvent()
{
aare.Set();
NonBlockingConsole.WriteLine("auto reset event set");
}
client UI:
private async void button1_Click(object sender, EventArgs e)
{
string value = await client.TestfuncAsync();
...
}
private void button2_Click(object sender, EventArgs e)
{
client.SetEvent();
}
NonBlockingConsole class: (reused from Does Console.WriteLine block?)
public static class NonBlockingConsole
{
private static BlockingCollection<string> m_Queue = new BlockingCollection<string>();
static NonBlockingConsole()
{
var thread = new Thread(
() =>
{
while (true) Console.WriteLine(m_Queue.Take());
}
);
thread.IsBackground = true;
thread.Start();
}
public static void WriteLine(string value)
{
value = DateTime.Now.ToString("<HH:mm:ss.fff>") + " " + value + " <ThreadID>: " + Thread.CurrentThread.ManagedThreadId.ToString();
m_Queue.Add(value);
}
}

How to use webclient and DownloadStringCompleted windows phone 8

I have class GetInfo (get object from server), Page1.xaml, Page2.xaml. I want tranmission object value from Page1 to Page2
This is my code
Class GetInfo
Class GetInfo{
Info use_info; //(Info is class)
public GetInfo(Info user_info)
{
this.user_info = user_info;
}
public void UseWebClient()
{
var client = new WebClient();
client.DownloadStringCompleted += (sender, e) =>
{
if (!string.IsNullOrEmpty(e.Result))
getInfo(e.Result);
};
client.DownloadStringAsync(new Uri("http://example.com/user_info.php?id=1"));
}
void getInfo()
{
I will Parse JSon string get from server become Info object...
}
}
Class Page1.cs//
Info user_info;
GetInfo userInfo;
public Page1()//constructor
{
userInfo = new GetInfo(user_info);
}
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
userInfo.UseWebClient();
//THIS IS PROBLEM
if(user_info.name != null) //name is public properties;
{
PhoneApplicationService.Current.State["user_info"] = user_info;
NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
}
else
{
MessageBox.Show("Check Connect!", "Warning", MessageBoxButton.OK)
if(result == MessageBoxResult.OK)
Application.Current.Terminate();
}
}
I know DownloadStringCompleted call when event LayoutRoot_Loaded() finish. Problem is I can't move to Page2 if LayoutRoot_Loaded() not finish.
I need solution to solve the problem
Thanks!

Retrying Event For SqlAzureExecutionStrategy

When working with SQL Azure, if I create my own RetryPolicy, e.g.:
var retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(10));
var retryPolicySQL = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy);
retryPolicySQL.Retrying += ....;
I am able to get notified when a retry is happening which is useful to log.
However, if I use what seems to be the new recommended strategy with EF6 and Azure - i.e. a custom DbConfiguration class something like this:
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
this.SetExecutionStrategy("System.Data.SqlClient", () =>
{
var strat = new SqlAzureExecutionStrategy();
// strat. No events
return strat;
});
}
}
I can't seem to find a way to hook into the retrying process. Is there a way to do this?
Implement the protected method called ShouldRetryOn by subclassing from SqlAzureExecutionStrategy. In that method you could put your logic to log or hook it into a handler as I show below.
public delegate void ChangedEventHandler(object sender, EventArgs e);
public class MyStrategy : SqlAzureExecutionStrategy
{
public event ChangedEventHandler Changed;
protected override bool ShouldRetryOn(Exception exception)
{
OnChanged(EventArgs.Empty);
return base.ShouldRetryOn(exception);
}
protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
Changed(this, e);
}
}
If you would perfer to just log the exception or the retry, you can do as follows:
public class LoggedSqlAzureExecutionStrategy : SqlAzureExecutionStrategy
{
protected override bool ShouldRetryOn(Exception exception)
{
var shouldRetry = base.ShouldRetryOn(exception);
if (shouldRetry)
{
// log retry
}
return shouldRetry;
}
}

SurfaceView Tutorial problems

I found a tutorial and it looks like this:
package com.djrobotfreak.SVTest;
public class Tutorial2D extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new Panel(this));
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private TutorialThread _thread;
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
}
#Override
public void onDraw(Canvas canvas) {
Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(_scratch, 10, 10, null);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
and it does not work, no matter what I do. I am trying to convert my code to surfaceview but I cant find any surfaceview programs that even work (besides the android-provided ones). Does anyone know what the error even is saying?
Here is my logcat info: http://shrib.com/oJB5Bxqs
If you get a ClassNotFoundException, you should check the Manifest file.
Click on the Application tab and look on the botton right side under "Attributes for".
If there is a red X mark under your Class Name, then click on the "Name" link and locate the correct class to load.

Postsharp Newbie - Why is args.Instance null?

New to PostSharp --- I'm trying out the NuGet version now and I'm trying to understand wny in the AuthoriseAttribute OnEntry method that the agrs.Instance value is null. I'm trying to implement authorsation that depends on the values of the object e.g. A customer who's been archived can't have a credit limit raised. I'm implementing the rules within other classes specific to the rules.
public class Program
{
static void Main(string[] args)
{
var c = new Customer();
c.RaiseCreditLimit(100000);
c.Error(00);
}
}
public class Customer
{
[AuthorizeActivity]
public void RaiseCreditLimit(int newValue)
{
}
[AuthorizeActivity]
public void Error(int newValue)
{
}
}
[Serializable]
public class AuthorizeActivityAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
//
//Why is args.Instance null???????????
//
if (args.Method.Name == "RaiseCreditLimit")
{
Debug.WriteLine(args.Method.Name + " started");
}
else
{
throw new Exception("Crap");
}
}
public override void OnExit(MethodExecutionArgs args)
{
Debug.WriteLine(args.Method.Name + " finished");
}
}
The answer is because you're not using it in your aspect. It's an optimization. If you use it in the aspect then it will be set. Change your aspect to consume instance and it will be there.
public override void OnEntry(MethodExecutionArgs args)
{
//
//Why is args.Instance null???????????
//
if (args.Method.Name == "RaiseCreditLimit")
{
Debug.WriteLine(args.Instance.GetType().Name);
Debug.WriteLine(args.Method.Name + " started");
}
else
{
throw new Exception("Crap");
}
}
For more info check out this article to see what else PostSharp does to optimize code http://programmersunlimited.wordpress.com/2011/03/23/postsharp-weaving-community-vs-professional-reasons-to-get-a-professional-license/