I'm trying to build a class where my thumbnail class is capturing a frame as a thumbnail of the videos users uploaded, things have gone good so far. I've written down the application on wpf app first and then decided to move to a class on my website as thumbnail.cs. Code is as shown below.
My problem is, the MediaOpenned event doesn't fire up so the execution cannot continue as its supposed to, i tried calling it myself and put a thread.sleep to handle the delay with the buffering of video and the code worked as i wanted. But i don't want to rely on sleep since it can be unstable due to server and heavy.. I need it to work with the event or something similar like that.
Any ideas or suggestions why event is not firing on .net? while working perfect on wpf? and what to do.
And millions of thanks of course!
thumbnail.cs class;
MediaPlayer myPlayer = new MediaPlayer();
public thumbnail()
{
myPlayer.Open(new Uri(#"C:\movie.wmv"));
myPlayer.Play();
myPlayer.IsMuted = true;
//this doesn't fire up
myPlayer.MediaOpened += new EventHandler(myPlayer_MediaOpened);
/*
when i do like this it works as i want but unstable and heavy because sleep
myPlayer_MediaOpened(null, null);
System.Threading.Thread.Sleep(5000);
*/
}
void myPlayer_MediaOpened(object sender, EventArgs e)
{
myPlayer.Position = TimeSpan.FromSeconds(myPlayer.NaturalDuration.TimeSpan.Seconds / 2);
RenderTargetBitmap RenderTarBitmap = new RenderTargetBitmap(400, 300, 1 / 96, 1 / 96, PixelFormats.Pbgra32);
DrawingVisual DVisual = new DrawingVisual();
DrawingContext DContext = DVisual.RenderOpen();
DContext.DrawVideo(myPlayer, new Rect(0, 0, 400, 300));
DContext.Close();
RenderTarBitmap.Render(DVisual);
myPlayer.Stop();
BitmapFrame BMPFrame = BitmapFrame.Create(RenderTarBitmap);
BitmapEncoder BMPEncoder = new JpegBitmapEncoder();
System.IO.FileStream FStream = new System.IO.FileStream(#"C:\movie.jpg", System.IO.FileMode.Create);
BMPEncoder.Frames.Add(BMPFrame);
BMPEncoder.Save(FStream);
FStream.Flush();
FStream.Close();
}
--------------------------------------------
UPDATE:
Allright so i've been trying to solve this for days now and god knows the person going to help me is directly going to heaven! Anyway i found that i'm not able to fire any event handlers related to MediaPlayer or my thumbnail.cs (which is hosted in app_code and called by a asmx webservice).
Tried some workarounds by using threads and implementing my own made event handlers checking whether movie is loaded or not.. no luck there either MediaPlayer doesn't let me touch its insides in another thread... And i didn't want to do more hack approach while able to solve with an easy event handler!
Searched the deepest google, found a thread on 2006 that a person assumed it may be a problem with x64 (well i'm using x64) but i couldn't found anything about that on msdn and hell its been 5 years!
So to sum up, i'm probably having a massive event not firing problem with either my class or my MediaPlayer control. And i need a saviour to help me catch the mediaOpenned event..
Thank you again.
Related
in my master page header i would like to display multiple images and have them change every 2 seconds or so. how would i go about implementing something like this?
Im using Microsoft visual studio 2010 and using vb.net
although i have just found this code, is there any way i get this to work in event handler of the timer. i understand it is not VB.net but can i use any imports?
protected void gettickvalue(object sender, EventArgs e);
{
Random RandomNumber = new Random();
int n = RandomNumber.Next(1, 9);
imgBanner.ImageUrl = System.String.Concat("images/banner_", n.ToString(), ".gif");
Considering that ASP runs server side, you probably don't want a timer running there. Your better solution is a JavaScript (client side) timer:
setInterval(function(){alert("Hello")},3000);
Created a workflow with basic as below.
Created a calss library, used ProgId, set comvisible true and registerd the assembly in the Tridion server.
This is the way i have tested:
Created a component
Finished the activity from the work list.
Navigated to the "Global Work list" and finished the Reviewer activity by myself by choosing the "Back to Author" step and clicked the "Finish" button.
The item is not moved to the author. but when i finish the activity again from the global work list, the item moved to author.
It seems that my code is not performing the activity because i tried removed the below VB script code and tried with the default automatic script code.
' Script for Automatic Activity Content Manager Workflow
FinishActivity "Automatic Activity Finished"
It behaves the same as above. so i decided my code is not worked. Can any one please help on this?
Below is the VBScript I used in the script box of "Back to Author":
Option Explicit
Dim workflowHandler
Set workflowHandler = CreateObject("CoreComponentWorkflow.WorkflowHandler");
If Not workflowHandler Is Nothing Then
Call workflowHandler.MoveBackToActivity(Cstr(CurrentWorkItem.ID, "Create or Edit Component")
End If
Set workflowHandler = Nothing
Below is the C# Code:
public void MoveBackToActivity(string workitemid, string strActivitytoMove)
{
try
{
Session session = new Session();
WorkItem workitem = new WorkItem(new TcmUri("workitemid"), session);
ActivityInstance currentactivity = workitem.Activity as ActivityInstance;
ProcessInstance procInstance = currentactivity.Process as ProcessInstance;
IEnumerable<ActivityInstance> ieActivities = procInstance.Activities
.Select (s => s)
.Where (w => w.Title.IndexOf(strActivitytoMove) !=-1)
.OrderByDescending(w =>w.StartDate);
if (ieActivities != null && ieActivities.Count<ActivityInstance>() > 0)
{
ActivityInstance targetactivity = ieActivities.ElementAt(0);
User lastperformuser = targetactivity.Performers.ElementAt(targetactivity.Performers.Count<User>() - 1);
ActivityFinish finish = new ActivityFinish(targetactivity.FinishMessage, lastperformuser, workitem.Session);
currentactivity.Finish(finish);
}
}
catch (Exception ex)
{
throw ex;
}
}
Be aware that you are using an API that is NOT supported in Automatic Activities. The only processes where you are allowed to use TOM.NET are Event System handlers and Template Building Blocks as documented here.
Automatic Workflow Activities - if not developed with VBScript - must use the CoreService interface.
The good news is that I know for a fact this works - plenty of people got it to work in many implementations. The bad news (for you) is that the error is in your code. Have you tried debugging/step-by-step through your code yet? You can attach to to the workflow process (cm_wf_svc.exe) and figure out what's wrong with the code much faster than we can.
Here's a really simple snippet to finish an activity with CoreService:
ActivityFinishData activityFinish = new ActivityFinishData
{
Message = "Automatically Finished from Expiration Workflow Extension"
};
ActivityInstanceData activityInstance =
(ActivityInstanceData)processInstance.Activities[0];
client.FinishActivity(activityInstance.Id, activityFinish, readOptions);
BTW - If you intended to use TOM.NET anyway, why did you bother asking which API to use?
Following the Nuno's answer, yes you should change the code to use TOM or Core Services. TOM .Net is not supported because it is using a different thread apartment than the underlying technology we use for workflow (COM).
About the issue I have checked that you are calling the activity like this.
Call workflowHandler.MoveBackToActivity(Cstr(CurrentWorkItem.ID, "Create or Edit Component")
It looks like the activity name is not matching. there are some strange characters between "Edit" and "Component"
I hope this helps.
Automatic activities are executed by the Workflow agent service. An Assigned state may indicate that it's just not being picked up by the service. Is your service running correctly, and are things like queue notifications set up properly?
I have 2 AIR applications (A and B) that are able to communicate via a LocalConnection object. I've verified that messages are definitely being sent/received appropriately.
I want to be able to have A tell B to come to the front. Both applications are full screen:
stage.fullScreenSourceRect = new Rectangle(0, 0, 1080, 1920);
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
I've tried several permutations, but as of yet nothing seems to work.
private function initSlave(channel: String): void {
conn = new LocalConnection();
conn.client = {
'activateSlave': activateSlave
};
conn.allowDomain("*");
conn.connect("_" + channel);
}
private function activateSlave(): void {
stage.nativeWindow.orderToFront();
// or
stage.nativeWindow.activate();
// or
stage.nativeWindow.alwaysInFront = true;
stage.nativeWindow.alwaysInFront = false;
}
If I leave both applications in windowed mode (stage.displayState = StageDisplayState.NORMAL), then toggling alwaysInFront actually works. Calling activate() or orderToFront() still do nothing. If I try to toggle alwaysInFront and then set the application to fullscreen, the application ends up fullscreen behind my windowed app. Maybe there is an event I should wait for before setting the app to fullscreen?
I found a thread mentioning that orderToFront() only works relative to windows within the same application, which explains why it doesn't seem to do anything.
Does anyone have any insights into pulling this off? Maybe there is a way for me to embed B into application A so they are actually the same application? I am not sure how to do this with an AIR application as simply as just loading the SWF due to requiring external resources.
As no one else has offered a solution, I'll just mention quickly the hack that I'm using. Basically I have 2 LocalConnection channels, one from A to B, and one from B to A.
The visible program (e.g. A) will then fade to white, set visible to false, and send a message to B giving up control. B has initialized itself with stage.nativeWindow.visible = false, and when it receives the message from A it goes visible as a full white screen and fades in the GUI. There is a slight offset before A sets visible to false to give B time to display, otherwise there is a pop in the brief moment when both windows are minimized.
Anyway, there you go, it's ugly but it actually works fairly well.
i am using Quartz.NET in my ASP.NET web application. i put the following code in a button click handler to make sure that it executes (for testing purposes):
Quartz.ISchedulerFactory factory = new Quartz.Impl.StdSchedulerFactory();
Quartz.IScheduler scheduler = factory.GetScheduler();
Quartz.JobDetail job = new Quartz.JobDetail("job", null, typeof(BackupJob));
Quartz.Trigger trigger = Quartz.TriggerUtils.MakeDailyTrigger(8, 30); // i edit this each time before compilation (for testing purposes)
trigger.StartTimeUtc = Quartz.TriggerUtils.GetEvenSecondDate(DateTime.UtcNow);
trigger.Name = "trigger";
scheduler.ScheduleJob(job, trigger);
scheduler.Start();
here's "BackupJob":
public class BackupJob : IJob
{
public BackupJob()
{
}
public void Execute(JobExecutionContext context)
{
NSG.BackupJobStart();
}
}
my question: why is "BackupJobStart()" not firing? i've used similar code before and it worked fine.
EDIT: #Andy White, i would have it in Application_Start in Global.asax. this doesn't work which is why i moved it to a button click handler to narrow down the problem.
Do you have the Quartz.NET logging hooked up? I once had a problem with a job not executing (I forget why), but once I got the Quartz.NET logging going, the problem was obvious.
It's worth a try (if you're not already doing it):
https://www.quartz-scheduler.net/documentation/quartz-2.x/quick-start.html
http://netcommon.sourceforge.net/
http://netcommon.sourceforge.net/documentation.html
Update: Simply add this to your program.cs to enable console logging:
Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter { Level = Common.Logging.LogLevel.Info};
Maybe it's a problem of time.
I've had the same problem as you, and I live in a country which time is UTC + 2. So, when I set the StartTimeUtc to the trigger, I used DateTime.Now, so the trigger didn't have to fire until two hours later, and I thought it has to be fired in the very moment my code started.
Look carefully the time of the trigger's execution and its StartTime
Another possibility is the way you're running the scheduler. I'm not totally sure, but you may run into problems trying to run a scheduling threads in an ASP.NET application. Putting the SchedulerFactory/Scheduler objects in a button click handler doesn't seem like it would give you the desired results.
You may need to create the scheduler at a more "global" level, so that it can run in the "background" of the application. It might also make sense to move any scheduled work into a separate windows service, so that you don't have to maintain the scheduler in the web app.
When you had success in the past, how were you invoking the scheduler?
In my case, there was an issue with IoC - there were some Interfaces that weren't implemented. I could see what was wrong with mine by adding logging:
Common.Logging.LogManager.Adapter = new Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter { Level = Common.Logging.LogLevel.Info};
to Program.cs as suggested by Andy White
Maybe I'm slow, but I just don't get why you would ever use an event that is not derived from an actual action (like clicking). Why go through the rigamarole of creating delegates and events when you can just call a method? It seems like when you create an event, all you're doing is creating a way for the caller to go through some complicated process to call a simple method. And the caller has to raise the event themselves! I don't get it.
Or maybe I'm just not grasping the concept. I get the need for events like OnClick and interactions with controls, but what about for classes? I tried to implement events for a class of mine, say, when the source of an item changed, but quickly realized that there was no point since I could just call a method whenever I wanted to perform a certain action instead of creating an event, raising an event, and writing an event handler. Plus, I can reuse my method, whereas I can't necessarily reuse my event handler.
Someone set me straight please. I feel like I'm just wrong here, and I want to be corrected. The last question I asked didn't really garner any sort of helpful answer.
Thanks.
I've always like the Radio Station metaphor.
When a radio station wants to broadcast something, it just sends it out. It doesn't need to know if there is actually anybody out there listening. Your radio is able to register itself with the radio station (by tuning in with the dial), and all radio station broadcasts (events in our little metaphor) are received by the radio who translates them into sound.
Without this registration (or event) mechanism. The radio station would have to contact each and every radio in turn and ask if it wanted the broadcast, if your radio said yes, then send the signal to it directly.
Your code may follow a very similar paradigm, where one class performs an action, but that class may not know, or may not want to know who will care about, or act on that action taking place. So it provides a way for any object to register or unregister itself for notification that the action has taken place.
Events in general can be a good way to decouple the listener/observer from the caller/raiser.
Consider the button. When someone clicks on the button, the click event fires. Does the listener of the button click care what the button looks like, does, or anything of that nature? Most likely not. It only cares that the click action has taken place, and it now goes and does something.
The same thing can be applied to anything that needs to same isolation/decoupling. It doesn't have to be UI driven, it can just be a logic separation that needs to take place.
Using events has the advantage of separating the class(es) which handle events from the classes which raise them (a la the Observer Pattern). While this is useful for Model View Controller (the button which raises click events is orthogonal to the class that handles them), it is also useful any time you want to make it easy to (whether at runtime or not) to keep the class which handles the events separated from the class which raises them (allowing you to change or replace them).
Basically, the whole point is to keep the classes which handle the events separated from the classes which raise them. Unnecessary coupling is bad, since it makes code maintainence much more difficult (since a change in one place in code will require changes in any pieces of code coupled to it).
Edit:
The majority of the event-handling you will do in Asp.Net will probably be to handle events from classes that are provided to you. Because such classes use event-handling, it makes it easy for you to interface with them. Often, the event will also serve to allow you to interact with the object that raised the event. For example, the databound controls usually raise an event right before they connect to the database, which you can handle in order to use runtime information to alter the arguments being passed to the stored procedure talking to your database, e.g. if the query string provides a page number parameter and the stored procedure has a page number argument.
Events can be used like messages to notify that something has happened, and an consumer can react to them in an appropriate way, so different components are loosely coupled. There's lots of things you can use events for, one example is auditing things that are happening in the system; the auditing component can consume various events and write out to a log when they are fired.
The things that you seem to be missing are two:
There are happenings in software that can take an arbitrary amount of time not only due to waiting for user input (async i/o, database queries and so on). If you launch an async i/o request you would want to subscribe to the event notifying you when the reading is done so you can do something with the data. This idea is generalized in .NET's BackgroundWorker class, which allows you to do heavy tasks in the background (another thread) and receive notifications in the calling thread when it's done.
There are happenings in software that are used by multiple clients not only a single one. For instance, if you have a plugin architecture where your main code offers hooks to plugin code, you could either do something like
foreach (Plugin p in getAvaliablePlugins()) { p.hook1(); }
in every hook all over your code which reduces flexibility (p cannot decide what to do, and has to provide the hook1 method publicly) or you can just
raiseEvent(hook1,this)
where all registered plugins can execute their code because they receive the event, letting them do their job as they see fit.
I think you're confusing ASP.NET's (mis)use of events, with plain ol' event handling.
We'll start with plain ol' event handling. Events is a (yet another) way of fulfilling the "Open [for extension]/Closed [for modification]" principle. When your class exposes an event, it allows external classes (perhaps classes that aren't even thought of, much less built, yet) to have code run by your class. That's a pretty powerful extension mechanism, and it doesn't require your class to be modified in any way.
As an example, consider a web server, that knows how to accept a request, but doesn't know how to process a file (I'll use bi-directional events here, where the handler can pass data back to the event source. Some would argue that's not kosher, but it's the first example that came to mind):
class WebServer {
public event EventHandler<RequestReceivedEventArgs> RequestReceived;
void ReceiveRequest() {
// lots of uninteresting network code here
var e = new RequestReceivedEventArgs();
e.Request = ReadRequest();
OnRequestReceived(e);
WriteResponse(e.Response);
}
void OnRequestReceived(RequestReceivedEventArgs e) {
var h = RequestReceived;
if (h != null) h(e);
}
}
Without changing the source code of that class - maybe it's in a 3rd party library - I can add a class that knows how to read a file from disk:
class FileRequestProcessor {
void WebServer_RequestReceived(object sender, EventArgs e) {
e.Response = File.ReadAllText(e.Request);
}
}
Or, maybe an ASP.NET compiler:
class AspNetRequestProcessor {
void WebServer_RequestReceived(object sender, EventArgs e) {
var p = Compile(e.Request);
e.Response = p.Render();
}
}
Or, maybe I'm just interested in knowing that an event happened, without affecting it at all. Say, for logging:
class LogRequestProcessor {
void WebServer_RequestReceived(object sender, EventArgs e) {
File.WriteAllText("log.txt", e.Request);
}
}
All of these classes are basically "injecting" code in the middle of WebServer.OnRequestReceived.
Now, for the ugly part. ASP.NET has this annoying little habit of having you write event handlers to handle your own events. So, the class that you're inheriting from (System.Web.UI.Page) has an event called Load:
abstract class Page {
public event EventHandler Load;
virtual void OnLoad(EventArgs e) {
var h = this.Load;
if (h != null) h(e);
}
}
and you want to run code when the page is loaded. Following the Open/Closed Principle, we can either inherit and override:
class MyPage : Page {
override void OnLoad(EventArgs e) {
base.OnLoad(e);
Response.Write("Hello World!");
}
}
or use eventing:
class MyPage : Page {
MyPage() {
this.Load += Page_Load;
}
void Page_Load(EventArgs e) {
Response.Write("Hello World!");
}
}
For some reason, Visual Studio and ASP.NET prefer the eventing approach. I suppose you can then have multiple handlers for the Load event, and they would all get run auto-magically - but I never see anyone doing that. Personally, I prefer the override approach - I think it's a bit clearer and you'll never have the question of "why am I subscribed to my own events?".