I'm writting a VSTO which loops through all slides, through all shapes and sets the title to a value.
I recognized that the memory consuption is going up after each run.
So therefore I minimized my code and let it run a 100 time which ends up allocating about 20MB Memory for every 100 runs.
My code is executed from a sidebar-button, the presentation has about 30 slides with titles.
My code looks like this for the button:
private void button1_Click(object sender, EventArgs e)
{
SetTitle_Direct();
Stopwatch watch = new Stopwatch();
watch.Start();
SetTitle_Direct();
watch.Stop();
//MessageBox.Show("Time spend: " + watch.Elapsed);
AMRefreshProgress.Maximum = 100;
AMRefreshProgress.Step = 1;
AMRefreshProgress.UseWaitCursor = true;
AMRefreshProgress.ForeColor = System.Drawing.ColorTranslator.FromHtml(ThisAddIn.amColor);
for (int i = 1; i <= 100; i++)
{
SetTitle_Direct();
AMRefreshProgress.PerformStep();
}
AMRefreshProgress.Value = 0;
AMRefreshProgress.UseWaitCursor = false;
Stopwatch watch2 = new Stopwatch();
watch2.Start();
SetTitle_Direct();
watch2.Stop();
MessageBox.Show("Time 1st run: " + watch.Elapsed + "\n Time 11th run: " + watch2.Elapsed);
}
The SetTitle_Direct() loops through the slides:
public void SetTitle_Direct()
{
PowerPoint.Presentation oPresentation = Globals.ThisAddIn.Application.ActivePresentation;
foreach (PowerPoint.Slide oSlide in oPresentation.Slides)
{
if (oSlide.Shapes.HasTitle == OFFICECORE.MsoTriState.msoTrue)
{
oSlide.Shapes.Title.TextFrame.TextRange.Text = "Test Main Title";
}
for (int iShape = 1; iShape <= oSlide.Shapes.Count; iShape++)
{
if (oSlide.Shapes[iShape].Type == Microsoft.Office.Core.MsoShapeType.msoPlaceholder)
{
if (oSlide.Shapes[iShape].PlaceholderFormat.Type == PowerPoint.PpPlaceholderType.ppPlaceholderSubtitle)
{
oSlide.Shapes[iShape].TextFrame.TextRange.Text = "Test Sub Title";
}
}
}
}
}
What causes the AddIn to allocate more and more memory - or how could this be avoided?
When you develop a VSTO based add-in you typically deal with COM objects (PowerPoint is a COM server). With each property or method call which returns a COM object, an object reference is typically increased which leads to keeping objects in memory until the reference counter is decreased and equals zero. So, I'd recommend using the Marshal.ReleaseComObject method to decrease an object reference and let the runtime to keep memory and make objects lifetime shorter.
To be able to release every COM object you must split long lines of property and method calls. Declare each property or method call on a separate line of code. Thus, you will be able to release every object and debug the code efficiently if anything strange happens around.
You may take a look at the When to release COM objects in Office add-ins developed in .NET article for more information.
Another alternative way is to use the garbage collector:
GC.Collect
GC.WaitForPendingFinalizers
GC.Collect
GC.WaitForPendingFinalizers
Related
I have just started using durable functions and needs some advise for how to do fan out pattern correctly. I have a FTP server where from I read all the files. I want to start an Activity function for each file. As I understand it the orchestrator function will be called everytime an Activity function is being executed. I just want to read the files once. To avoid calling the code that read the files and starts the activity functions multiple times, what is the recommended approach? Is it having an activity function that that add's all the activity functions or is it using the IsReplaying property, or something different?
[FunctionName("OrchestrationMoveFilesToBlob")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();
if (!context.IsReplaying)
{
// Do you call your database here and make a call to CallActivityAsync for each row?
}
// doing it here is properly very wrong as it will be called multiple times
var tasks = new Task<string>[7];
for (int i = 0; i < 7; i++)
{
tasks[i] = context.CallActivityAsync<string>("E2_CopyFileToBlob",""); }
await Task.WhenAll(tasks);
return outputs;
}
When looking into the sample in the link below this actually calls it directly in the orchestrator function? Is this not really bad? It continue adding same activities again and again .... ?
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-cloud-backup
Not sure I understand what you try to achieve but your code looks not bad so far. An orchestration is just called once (and maybe some times more for replay but this is not your problem here). From your orchestration you can call in a fan out all your activity functions (gathering a file from an ftp) each activity function one file. await Task.WhenAll(tasks) is your fan in. (you can use a List<Task> instead of the array and call .Add(task) on it if you want. In order to not edit your code I copied it here and added some comments and questions (feel free to edit here):
[FunctionName("OrchestrationMoveFilesToBlob")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context)
{
var outputs = new List<string>();
if (!context.IsReplaying)
{
// just needed for things that should not happen twice like logging....
}
// if your work isn't a fixed list just call an activity
// which replies with the list of work here (e.g. list of filenames)
var tasks = new Task<string>[7]; // can be a List<Task> too
for (int i = 0; i < 7; i++)
{
tasks[i] = context.CallActivityAsync<string>("E2_CopyFileToBlob","");
}
await Task.WhenAll(tasks);
return outputs; // currently an empty list. What do you want to give back?
}
I was wondering, is it possible to send a Future through a stream that can get resolved after "reception" by a listener?
Cheers!
Futures are just values, so you can make a Stream<Future>. The receiver of the future can then wait on the future normally, and you can complete it at any point in between
It's generally frowned upon, though, because of the double asynchrony.
What it does is to make the receiver wait for a stream event, which you emit at one point, then have the receiver wait again for the actual result which may come at an even later point.
The most urgent issue with that is that you don't always know whether the future has been received yet when you complete it. Maybe the receiver paused the stream, maybe you are quicker than you expected. In any case, if you complete the future with an error before it has been received, then that error is probably going to end up uncaught, which may crash your entire program.
It also has bad usability. If you instead waited for the future on the sending side and only sent the event when the result was ready, it's easier and simpler for the receiver (they just get the result as normal), and it's usually just as good at achieving what you want to achieve.
If you really have a situation where a number of asynchronous results (futures) can complete in any order, but the receiver needs to know the original order of the futures themselves, then I guess a Stream<Future<X>> can be the answer (but do consider whether your solution is just needlessly complicated).
Example (in full generality):
Stream<Future<int>> randomDelays() {
var controller = StreamController<Future<String>>();
controller.onListen = () {
var rng = Random();
for (int i = 0; i < 10; i++) {
var delay = rng.nextInt(10);
var completer = Completer<int>();
controller.add(completer.future);
Timer(Duration(seconds: delay), () {
completer.complete(i);
});
}
controller.close();
}
}
or simpler:
Future<Stream<int>> randomDelays() async* {
var rng = Random();
for (int i = 0; i < 10; i++) {
var delay = rng.nextInt(10);
yield Future.delayed(Duration(seconds: delay), () => i);
}
}
I am not sure why your want that but sure you can do that:
import 'dart:async';
void main() {
final controller = StreamController<FutureOr<int>>();
controller.sink.add(Future.delayed(Duration(seconds: 1), () => 5));
print(controller.stream.first.runtimeType); // _Future<FutureOr<int>>
}
When you add a Future to the sink it will not be automatically awaited. So what you get out from the Stream are Future objects if you put Future objects in the sink.
I really like how jazelcast jet works with java util streams but when I run those streams I am getting confused how is this running in a distributed way.
public class IstreamHazelcastDemo {
public static void main( String[] args ) {
JetInstance jet = Jet.newJetInstance();
Jet.newJetInstance();
IListJet<String> list = jet.getList("list");
for(int i = 0; i < 50; i++) {
list.add("test" + i);
}
DistributedStream.fromList(list)
.map(word -> {
System.out.println("word: " + word);
return word.toUpperCase();
})
.collect(DistributedCollectors.toIList("sink"))
.forEach(System.out::println);
}
}
This is a simple example where I create a jet instance first bu running another main program and then run this code so it forms a cluster of 2 nodes. So when I run the above code I was expecting to see the print statement inside map function to be printed in both the nodes since I thought its distributed and will send to multiple nodes. But it always executed the whole flow only in one node. I am trying to think how is this distributed or is it me who is lacking the understanding of hazelcast Jet.
Thanks
Try this change and you should see a difference
IMapJet<String, String> map = jet.getMap("map");
for(int i = 0; i < 50; i++) {
map.put("test" + i, "test" + i);
}
DistributedStream.fromMap(map)
.map(entry -> {
System.out.println("word: " + entry.getKey());
return entry.getKey().toUpperCase();
})
.collect(DistributedCollectors.toIList("sink"))
.forEach(System.out::println);
The difference here is around distribution and partitioning.
A list is distributed, meaning sent to the grid for hosting, but it is still a single object. One grid member holds it, so you'll see a single stream of sysout from the mapper.
A map is distributed, but is also partitioned, meaning the hosting is split across the grid members. If there are two grid members they'll have roughly half of the map content each. So you'll see multiple streams of sysout.
I've read several related posts and even posted and answer here but it seems like I was not able to solve the problem.
I have 3 Activities:
Act1 (main)
Act2
Act3
When going back and forth Act1->Act2 and Act2->Act1 I get no issues
When going Act2->Act3 I get no issues
When going Act3->Act2 I get occasional crashes with the following error: java.lang.IllegalStateException: trying to requery an already closed cursor android.database.sqlite.SQLiteCursor#.... This is a ListView cursor.
What I tried:
1. Adding stopManagingCursor(currentCursor);to the onPause() of Act2 so I stop managing the cursor when leaving Act2 to Act3
protected void onPause()
{
Log.i(getClass().getName() + ".onPause", "Hi!");
super.onPause();
saveState();
//Make sure you get rid of the cursor when leaving to another Activity
//Prevents: ...Unable to resume activity... trying to requery an already closed cursor
Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor();
stopManagingCursor(currentCursor);
}
When returning back from Act3 to Act2 I do the following:
private void populateCompetitorsListView()
{
ListAdapter currentListAdapter = getListAdapter();
Cursor currentCursor = null;
Cursor tournamentStocksCursor = null;
if(currentListAdapter != null)
{
currentCursor = ((SimpleCursorAdapter)currentListAdapter).getCursor();
if(currentCursor != null)
{
//might be redundant, not sure
stopManagingCursor(currentCursor);
// Get all of the stocks from the database and create the item list
tournamentStocksCursor = mDbHelper.retrieveTrounamentStocks(mTournamentRowId);
((SimpleCursorAdapter)currentListAdapter).changeCursor(tournamentStocksCursor);
}
else
{
tournamentStocksCursor = mDbHelper.retrieveTrounamentStocks(mTournamentRowId);
}
}
else
{
tournamentStocksCursor = mDbHelper.retrieveTrounamentStocks(mTournamentRowId);
}
startManagingCursor(tournamentStocksCursor);
//Create an array to specify the fields we want to display in the list (only name)
String[] from = new String[] {StournamentConstants.TblStocks.COLUMN_NAME, StournamentConstants.TblTournamentsStocks.COLUMN_SCORE};
// and an array of the fields we want to bind those fields to (in this case just name)
int[] to = new int[]{R.id.competitor_name, R.id.competitor_score};
// Now create an array adapter and set it to display using our row
SimpleCursorAdapter tournamentStocks = new SimpleCursorAdapter(this, R.layout.competitor_row, tournamentStocksCursor, from, to);
//tournamentStocks.convertToString(tournamentStocksCursor);
setListAdapter(tournamentStocks);
}
So I make sure I invalidate the cursor and use a different one. I found out that when I go Act3->Act2 the system will sometimes use the same cursor for the List View and sometimes it will have a different one.
This is hard to debug and I was never able to catch a crashing system while debugging. I suspect this has to do with the time it takes to debug (long) and the time it takes to run the app (much shorter, no pause due to breakpoints).
In Act2 I use the following Intent and expect no result:
protected void onListItemClick(ListView l, View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
Intent intent = new Intent(this, ActivityCompetitorDetails.class);
intent.putExtra(StournamentConstants.App.competitorId, id);
intent.putExtra(StournamentConstants.App.tournamentId, mTournamentRowId);
startActivity(intent);
}
Moving Act1->Act2 Act2->Act1 never gives me trouble. There I use startActivityForResult(intent, ACTIVITY_EDIT); and I am not sure - could this be the source of my trouble?
I would be grateful if anyone could shed some light on this subject. I am interested in learning some more about this subject.
Thanks,D.
I call this a 2 dimensional problem: two things were responsible for this crash:
1. I used startManagingCursor(mItemCursor); where I shouldn't have.
2. I forgot to initCursorAdapter() (for autocomplete) on onResume()
//#SuppressWarnings("deprecation")
private void initCursorAdapter()
{
mItemCursor = mDbHelper.getCompetitorsCursor("");
startManagingCursor(mItemCursor); //<= this is bad!
mCursorAdapter = new CompetitorAdapter(getApplicationContext(), mItemCursor);
initItemFilter();
}
Now it seems to work fine. I hope so...
Put this it may work for you:
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
orderCursor.requery();
}
This also works
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
startManagingCursor(Cursor);
}
I have the following test code (based on standard monodroid HelloWorld)
namespace TestGREF
{
[Activity (Label = "TestGREF", MainLauncher = true)]
public class Activity1 : Activity
{
int count = 1;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate {
button.Text = string.Format ("{0} clicks!", count++);
for(int i=0;i<10000;i++){
new Java.Lang.Object(new System.IntPtr(i));
//...some stuff here. Instead of Java.Lang.Object may be
//something much more useful.
}
//If uncomment here, looks ok
//GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
};
}
}
}
If I click the button 5-6 times, application crashes.
I know this happens because of global refences (GREF) limit (described here, "Unexpected NullReferenceExceptions" section). The question is: what to do with it? What is the best practice? If possible, with code example please
If uncomment GC.Collect() call, all seems working, but calling GC too often is too exspensive for performance. Another popular design is to put new statement put of loop, but it is not always possible cause of program logic.
Any more ideas?
You need to release all unmanaged objects when they no longer needed. All classes that inherits from Android.Runtime.IJavaObject also inherits IDisposable so you need to dispose them.
Here is part from my project
private Spinner _spType;
private ArrayAdapter _arrayAdapter;
protected override void OnCreate(Android.OS.Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
_spType = FindViewById<Spinner>(Resource.Id.spinnerType);
_arrayAdapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleSpinnerItem, new[] {"1","2","3","4","5"});
_spType.Adapter = _arrayAdapter;
}
public override void Finish()
{
if (_spType != null)
_spType.Dispose();
if (_arrayAdapter != null)
_arrayAdapter.Dispose();
base.Finish();
}
for(int i=0;i<10000;i++){
var obj = new Java.Lang.Object(new System.IntPtr(i));
//...some stuff here. Instead of Java.Lang.Object may be
//something much more useful.
obj.Dispose(); //Deletes an object and GREF too.
//Cannot be used if object is still used in dalvik VM
}
If you cannot use Dispose() (for example, unmanaged object is a part of layout, which will be used by android lated, but not by C# code), use GC.Collect() wisely. GC.Collect() kills all the GREFs to variables, which are out of usage by Mono Environment and out of current scope.
Here is article about GC and memory management in monodroid. It can be helpful for you
http://docs.xamarin.com/android/advanced_topics/garbage_collection