I tried to write simple program, that simulates lottery and I got some behavior I cannot understand, nor fix:
To keep it simple I excluded code that is irrelevant to the problem
PROGRAM: On click it should Get six different numbers (between 1 and 49) entered by user, get six different random numbers (between 1 and 49) compare them and repeat getting random numbers and comparing with entered until there are three matches.
What is relevant, I am calling function GetResults() on button click and passing to it two parameters (method definition below). I simplified it to button click to show you. There are some conditions and function calls there, but they are working and problem exists even without them so that's why image example on the bottom may be a little different.
private void btnCheck_Click(object sender, EventArgs e)
{
lotto.GetResults(3, ref listRndNumLabels);
lblMatches.Text = lotto.CurrentMatches.ToString();
lblTryCounter.Text = lotto.NumberOfTries.ToString();
lblBalance.Text = lotto.Balance.ToString() + " zł";
lblThreesAmmount.Text = lotto.ThreesAmmount.ToString();
lblFoursAmmount.Text = lotto.FoursAmmount.ToString();
lblFivesAmmount.Text = lotto.FivesAmmount.ToString();
lblSixesAmmount.Text = lotto.SixesAmmount.ToString();
}
The method GetResults() takes 3 as number of desired matches and List of Labels which is updated at the end
public void GetResults(int Choice, ref List<Label> listLblRndNum)
{
_currentMatches = 0;
int desiredNumberOfMatches = Choice;
// while we got other ammount of matches than three, go again
while (_currentMatches != desiredNumberOfMatches)
{
_numberOfTries++;
// get list of mutually exclusive 6 numbers betweeen 1 and 49
var tempList = GetRndNums();
// insert random numbers to list
_listLotteryNumbers.Clear();
for (int i = 0; i < 6; i++)
{
_listLotteryNumbers.Insert(i, tempList[i]);
}
_balance -= _ticketCost;
_currentMatches = 0;
// get number of matches
for (int i = 0; i < 6; i++)
{
foreach (int num in _listLotteryNumbers)
{
if (_listSelectedNumbers[i] == num)
{
_currentMatches++;
}
}
}
//FrmLotto.lbResults.Items.Add(_numberOfTries.ToString() + " - _currentMatches: " + _currentMatches.ToString());
//FrmLotto.lbResults.Items.Add(_numberOfTries.ToString() + " - tempList { " + tempList[0] + " " + tempList[1] + " " + tempList[2] + " " + tempList[3] + " " + tempList[4] + " " + tempList[5] + " }");
//FrmLotto.lbResults.Items.Add(_numberOfTries.ToString() + " - _listLotteryNumbers { " + _listLotteryNumbers[0] + " " + _listLotteryNumbers[1] + " " + _listLotteryNumbers[2] + " " + _listLotteryNumbers[3] + " " + _listLotteryNumbers[4] + " " + _listLotteryNumbers[5] + " }");
//FrmLotto.lbResults.Items.Add(_numberOfTries.ToString() + " - _listSelectedNumbers { " + _listSelectedNumbers[0] + " " + _listSelectedNumbers[1] + " " + _listSelectedNumbers[2] + " " + _listSelectedNumbers[3] + " " + _listSelectedNumbers[4] + " " + _listSelectedNumbers[5] + " }");
// update stats
if (_currentMatches == 3)
{
_threesAmmount++;
_balance += 10;
}
else if (_currentMatches == 4)
{
_foursAmmount++;
_balance += 100;
}
else if (_currentMatches == 5)
{
_fivesAmmount++;
_balance += 3500;
}
else if (_currentMatches == 6)
{
_sixesAmmount++;
_balance += 1000000;
}
//FrmLotto.lbResults.Items.Add(_numberOfTries.ToString() + " - Threes Ammount right after updating: " + _threesAmmount);
//FrmLotto.lbResults.Items.Add("");
// this gets out of the loop if user has chosen from ddl to run once, it is irrelevant here
if (desiredNumberOfMatches == -1)
break;
}
// finally update Labels with the desired result
for (int i = 0; i < 6; i++)
{
listLblRndNum[i].Text = _listLotteryNumbers[i].ToString();
}
}
And this is the function which gets random numbers:
public List<int> GetRndNums()
{
List<int> listRndNums = new List<int>();
Random rndNum = new Random();
for (int i = 0; i < 6; i++)
{
int myNum = 0;
do
myNum = rndNum.Next(1, 49);
while (listRndNums.Contains(myNum));
listRndNums.Add(myNum);
}
listRndNums.Sort();
return listRndNums;
}
So program works as expected if loop run once, or if there is delay after each loop, or if I put breakpoint in the loop.
OTHERWISE there is an unexpected behavior, loop run more than once for the same data (for the same lists), I don't understand why.
look at the images:
Program run once, I clicked button five times, to show you that results are fine:
(btw = Sprawdź = Check, raz = once, do pierwszej trójki = until 3 matches)
http://ultraimg.com/jHQY
And when I select until 3 matches (or click button from the code example above) I am receiving wrong result, loop runs multiple times for the same values.
http://ultraimg.com/jHQn
Would be really grateful for help, I am learning, I know that many parts of code could be improved, many parts are for temp debugging purposes only. But this behavior, I simply don't get it.
In order to fix this problem you should try making
Random rndNum = new Random();
a static variable.
See this :
http://msdn.microsoft.com/en-us/library/system.random.aspx
Pseudo-random numbers are chosen with equal probability from a finite set of numbers. The chosen numbers are not completely random because a definite mathematical algorithm is used to select them, but they are sufficiently random for practical purposes. The current implementation of the Random class is based on Donald E. Knuth's subtractive random number generator algorithm. For more information, see D. E. Knuth. "The Art of Computer Programming, volume 2: Seminumerical Algorithms". Addison-Wesley, Reading, MA, second edition, 1981.
The random number generation starts from a seed value. If the same
seed is used repeatedly, the same series of numbers is generated. One
way to produce different sequences is to make the seed value
time-dependent, thereby producing a different series with each new
instance of Random. By default, the parameterless constructor of the
Random class uses the system clock to generate its seed value, while
its parameterized constructor can take an Int32 value based on the
number of ticks in the current time. However, because the clock has
finite resolution, using the parameterless constructor to create
different Random objects in close succession creates random number
generators that produce identical sequences of random numbers. The
following example illustrates that two Random objects that are
instantiated in close succession generate an identical series of
random numbers.
byte[] bytes1 = new byte[100];
byte[] bytes2 = new byte[100];
Random rnd1 = new Random();
Random rnd2 = new Random();
rnd1.NextBytes(bytes1);
rnd2.NextBytes(bytes2);
Console.WriteLine("First Series:");
for (int ctr = bytes1.GetLowerBound(0);
ctr <= bytes1.GetUpperBound(0);
ctr++) {
Console.Write("{0, 5}", bytes1[ctr]);
if ((ctr + 1) % 10 == 0) Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("Second Series:");
for (int ctr = bytes2.GetLowerBound(0);
ctr <= bytes2.GetUpperBound(0);
ctr++) {
Console.Write("{0, 5}", bytes2[ctr]);
if ((ctr + 1) % 10 == 0) Console.WriteLine();
}
// The example displays the following output to the console:
// First Series:
// 97 129 149 54 22 208 120 105 68 177
// 113 214 30 172 74 218 116 230 89 18
// 12 112 130 105 116 180 190 200 187 120
// 7 198 233 158 58 51 50 170 98 23
// 21 1 113 74 146 245 34 255 96 24
// 232 255 23 9 167 240 255 44 194 98
// 18 175 173 204 169 171 236 127 114 23
// 167 202 132 65 253 11 254 56 214 127
// 145 191 104 163 143 7 174 224 247 73
// 52 6 231 255 5 101 83 165 160 231
//
// Second Series:
// 97 129 149 54 22 208 120 105 68 177
// 113 214 30 172 74 218 116 230 89 18
// 12 112 130 105 116 180 190 200 187 120
// 7 198 233 158 58 51 50 170 98 23
// 21 1 113 74 146 245 34 255 96 24
// 232 255 23 9 167 240 255 44 194 98
// 18 175 173 204 169 171 236 127 114 23
// 167 202 132 65 253 11 254 56 214 127
// 145 191 104 163 143 7 174 224 247 73
// 52 6 231 255 5 101 83 165 160 231
This problem can be avoided by creating a single Random object rather
than multiple ones. To improve performance, create one Random object
to generate many random numbers over time, instead of repeatedly
creating a new Random objects to generate one random number. To
generate a cryptographically secure random number suitable for
creating a random password, for example, use a class derived from
System.Security.Cryptography.RandomNumberGenerator such as
System.Security.Cryptography.RNGCryptoServiceProvider.
Related
I have a list which contains some documents (for simplicity strings). Now the list is getting populated slowly. What I want to do is when the size of the list reaches 20 I want to call another function that will print these strings asynchronously without stopping the main method. After lot of searching I have managed to put together this code
public void DoStuff()
{
Class1 p = new Class1();
List<string> list = new List<string> { };
var TList = new List<Task>();
int i = 0;
while (i < 90)
{
list.Add(i.ToString());
if (list.Count == 20)
{
Console.WriteLine("List contents when calling: " + list[0]);
TList.Add(Task.Run(() => publishDoc(list)));
list.Clear();
}
i++;
}
if (list.Count != 0)
{
TList.Add(Task.Run(() => publishDoc(list)));
}
Task.WhenAll(TList).Wait();
Console.WriteLine("Done DoStuff");
}
public async Task publishDoc(List<string> docs)
{
Console.WriteLine(iter++ + " " + docs[0]);
await Task.Run(() => Thread.Sleep(1000));
foreach (var val in docs)
{
Console.Write(val + " ");
}
Console.WriteLine();
}
This is what I am getting as output
List contents when calling: 0
List contents when calling: 20
List contents when calling: 40
List contents when calling: 60
1 80
3 80
0 80
2 80
4 80
80 80 80 80 81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
80 81 82 83 84 85 86 87 88 89
Done DoStuff
Done Main
I can't figure out why it is only printing the last passed data i.e. why the passed list is getting overwritten.
Now if I do this
public void DoStuff()
{
Program2 p = new Program2();
List<string> list = new List<string> { };
int i = 0;
while (i < 90)
{
list.Add(i.ToString());
if (list.Count == 20)
{
Console.WriteLine("List contents when calling: " + list[0]);
var tasks = publishDoc(list);
if (tasks.Result == "Done")
{
Console.WriteLine("Done " + list[0]);
}
list.Clear();
}
i++;
}
if (list.Count != 0)
{
var tasks = publishDoc(list);
if (tasks.Result == "Done")
{
Console.WriteLine("Done " + list[0]);
}
}
Console.WriteLine("Done DoStuff");
}
public async Task<string> publishDoc(List<string> docs)
{
Console.WriteLine(iter++ + " " + docs[0]);
foreach (var val in docs)
{
Console.Write(val + " ");
}
Console.WriteLine();
return await Task.Run(() => "Done");
}
I get this output
List contents when calling: 0
0 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Done 0
List contents when calling: 20
1 20
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Done 20
List contents when calling: 40
2 40
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
Done 40
List contents when calling: 60
3 60
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
Done 60
4 80
80 81 82 83 84 85 86 87 88 89
Done 80
Done DoStuff
Done Main
This is giving the correct output but is doing it synchronously which I don't want. Please help and thanks in advance.
you have to do like this , as in loop it points to same instance of list every time that might causing issue , so I suggest you create copy of list before passing it to function publishDoc
while (i < 90)
{
list.Add(i.ToString());
if (list.Count == 20)
{
List<string> copy = list.ToList();
Console.WriteLine("List contents when calling: " + copy[0]);
TList.Add(Task.Run(() => publishDoc(copy)));
list.Clear();
}
i++;
}
Refer this answer also : Starting Tasks In foreach Loop Uses Value of Last Item
So I wrote a test code (trying to teach myself how to make sorting algorithms), which looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static string Compile (List<int> array)
{
string output = "";
foreach (var item in array)
{
output += item.ToString() + " ";
}
return output;
}
static List<int> InsertSort(List<int> listToSort)
{
List<int> deliverList = new List<int>();
deliverList = listToSort;
int j = 0;
int iterator = 0;
for (int i = 1; i < deliverList.Count; i++)
{
j = i;
while(j>0)
{
if(deliverList[j] < deliverList[j-1])
{
int temp = deliverList[j - 1];
deliverList[j - 1] = deliverList[j];
deliverList[j] = temp;
}
Console.WriteLine("Iteration #[" + iterator.ToString() + "]: " + Compile(deliverList));
iterator++;
j--;
}
}
return deliverList;
}
static void Main(string[] args)
{
List<int> unsorted = new List<int>();
List<int> sorted = new List<int>();
Random random = new Random();
for (int i = 0; i < 10; i++)
{
unsorted.Add(random.Next(0, 100));
}
sorted = InsertSort(unsorted);
Console.WriteLine("Unsorted Array: " + Compile(unsorted));
Console.WriteLine("Sorted Array: " + Compile(sorted));
Console.ReadKey();
}
}
}
For some reason, when I use the InsertSort method on the "sorted" array, the "unsorted" array is also changed, outputting the sorted array two times and not letting me see the unsorted one. What exactly is happening here?
PS: Compile is just a simple method that compiles a list into a string with the elements separated by spaces.
You have the code deliverList = listToSort; which makes deliverList reference the same list as listToSort. They become synonyms.
Instead you should write:
List<int> deliverList = listToSort.ToList();
That will make a copy of the list - and now they will both be different.
Your code now would output:
Iteration #[0]: 52 88 93 69 35 21 63 47 2 17
Iteration #[1]: 52 88 93 69 35 21 63 47 2 17
...
Iteration #[43]: 2 17 21 35 47 52 63 69 88 93
Iteration #[44]: 2 17 21 35 47 52 63 69 88 93
Unsorted Array: 88 52 93 69 35 21 63 47 2 17
Sorted Array: 2 17 21 35 47 52 63 69 88 93
you need to make a copy of the list
List<int> deliverList = listToSort.Select(x=>x);
My program currently reads in the values from a text file that is in the .HRM format and will parse them depending on the column the data is contained in and insert the data into the appropriate row. The code I have currently will read in the code and below that i attempted to make the code into a list which is then inserted into the datagridview but I think I have done this incorrectly due to not having the array set up correctly as I am not sure how it would split between the columns nor how I would decide which row of the datagridview the data would be inserted into. This is the code I am using to load in the file:
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
{
string filePath = #"F:\testdata.hrm";
if (File.Exists(filePath))
processfile(filePath);
else
System.Console.WriteLine("Error - File {0} not Found", filePath);
System.Console.ReadKey();
}
}
// static void processfile(String filePath)
// {
// List<string[]> result = File.ReadAllLines("filePath") //read all lines in the file
// .SkipWhile(x => x != "[HRData]") //skip lines until reaching the "[HRData]"
// .Select(x => x.Split(null, StringSplitOptions.RemoveEmptyEntries)) //split line by whitespace to get numbers in line
// .ToList(); // convert the result to a list
// result.ForEach(x => dataGridView1.Rows.Add(x));
}
}
}
This is the data I am reading in:
[HRData]
91 154 70 309 83 6451
91 154 70 309 83 6451
92 160 75 309 87 5687
94 173 80 309 87 5687
96 187 87 309 95 4662
100 190 93 309 123 4407
101 192 97 309 141 4915
103 191 98 309 145 5429
106 190 99 309 157 4662
106 187 98 309 166 4399
107 186 97 309 171 4143
107 185 97 309 170 4914
108 184 96 309 171 5426
108 183 95 309 170 5688
So what I will want to do is read each column in the file then adding each column into a seperate array for each of the columns and they will then be inserted into the datagridview in the appropriate columns. I tried to code this but I'm not sure what I did wrong so any help would be appreciated.
You can do like this:
var lines = File.ReadAllLines(#"F:\testdata.hrm").Skip(1);
foreach (var line in lines)
dataGridView1.Rows.Add(line.Split(
new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
EDIT:
Based on you comment, you want rotate row to column, and column to row. You can do like bellow:
var lines = File.ReadAllLines(#"F:\testdata.hrm").Skip(1);
List<string[]> list = new List<string[]>();
foreach (var line in lines)
{
list.Add(line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
}
for (int i = 0; i < 6; i++)
{
List<string> cols = new List<string>();
for (int j = 0; j < list.Count; j++)
{
cols.Add(list[j][i]);
}
dataGridView1.Rows.Add(cols.ToArray());
}
To add header to a row:
List<string> rowHeaders = new List<string> { "A", "B", "C", "D", "E", "F", "G" };
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
dataGridView1.Rows[i].HeaderCell.Value = rowHeaders[i];
}
It looks like you are implementing Linq into C# code? Also, you want to separate each column into an array of itself, but you have only declared one array? If you want each column into its own array, you need to declare multiple arrays, or you need to declare a 3-D array. I would recommend using a foreach loop that this:
foreach(string column in filepath)
{
string[] result = File.ReadAllLines("filePath");
string dataColumn = dataGridView1.Rows.Add(result));
}
In c#, async and await are turned into a state machine at compile time. My problem is hitting each piece of the state machine. I've decompiled the code and ran my exact same unit test against it to find out which branch I'm missing.
49 void IAsyncStateMachine.MoveNext()
4 50 {
4 51 int result1 = 0;
52 try
4 53 {
4 54 bool flag = true;
55 TaskAwaiter<int> awaiter;
4 56 switch (this._state)
57 {
58 case -3:
0 59 goto label_6;
60 case 0:
1 61 awaiter = this._awaiter2;
1 62 this._awaiter2 = new TaskAwaiter<int>();
1 63 this._state = -1;
1 64 break;
65 default:
3 66 awaiter = this._this._additionAsync.Add(this.value1, this.value2).GetAwaiter();
2 67 if (!awaiter.IsCompleted)
1 68 {
1 69 this._state = 0;
1 70 this._awaiter2 = awaiter;
1 71 this._builder.AwaitUnsafeOnCompleted<TaskAwaiter<int>, CalculatorAsync.d__0>(ref awaiter, ref this);
1 72 flag = false;
1 73 return;
74 }
1 75 break;
76 }
2 77 int result2 = awaiter.GetResult();
2 78 awaiter = new TaskAwaiter<int>();
2 79 this._results1 = result2;
2 80 result1 = this._results1;
2 81 }
1 82 catch (Exception ex)
1 83 {
1 84 this._state = -2;
1 85 this._builder.SetException(ex);
1 86 return;
87 }
88 label_6:
2 89 this._state = -2;
2 90 this._builder.SetResult(result1);
4 91 }
Above you can see that line 59 is hit 0 times in terms of coverage.
According to this article http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine it's hit when the machine is requested to stop. I haven't been able cancel the async call in a manner that hits the case.
This is a test I thought would hit it but isn't.
[Test]
[ExpectedException("System.InvalidOperationException")]
public async void DecompiledCancellationTest()
{
var expectedResult = 4;
var tcs = new TaskCompletionSource<int>();
tcs.SetResult(4);
var additionHandler = new Mock<IAdditionHandler>();
additionHandler.Setup(x => x.Add(2, 2)).Returns(tcs.Task);
tcs.SetCanceled();
var calculator = new CalculatorAsync(additionHandler.Object);
var aTaskResponse = calculator.AddDecompiled(2, 2);
var aResponse = await aTaskResponse;
Assert.AreEqual(expectedResult, aResponse);
}
I've uploaded a sample to github
Using Asp.Net 4.5, Nunit 2.6.4, OpenCover 4.5.3522, and ReportGenerator 2.1.4.0
How do I get that line covered?
I am trying to implement in MonoTouch the ability to record video with high frame rates (available since iOS 7). Following Apple documentation, we are enumerating the available video formats like this:
AV.AVCaptureDeviceFormat highSpeedFormat = null;
m_captureSession.BeginConfiguration();
double requestedFrameRate = 120;
for (int i = 0; i < avVideoCaptureDevice.Formats.Length; i++)
{
AV.AVCaptureDeviceFormat format = avVideoCaptureDevice.Formats[i];
CM.CMFormatDescription fd = format.FormatDescription;
Media.Logger.Log(string.Format("format = {0}", format));
Media.Logger.Log(string.Format("dim = {0}x{1}", fd.VideoDimensions.Width, fd.VideoDimensions.Height));
for (int j = 0; j < format.VideoSupportedFrameRateRanges.Length; j++)
{
AV.AVFrameRateRange range = format.VideoSupportedFrameRateRanges[j];
Media.Logger.Log(string.Format(" range: {0}", range));
if (System.Math.Abs(requestedFrameRate - range.MaxFrameRate) <= 1.0 && fd.VideoDimensions.Width == 1280)
{
Media.Logger.Log(">>>> found a matching format");
highSpeedFormat = format;
}
}
}
Once we have found the desired high frame rate format, we set it to the video capture device like this:
if (highSpeedFormat != null)
{
NS.NSError error;
avVideoCaptureDevice.LockForConfiguration(out error);
avVideoCaptureDevice.ActiveFormat = highSpeedFormat;
CM.CMTime frameDuration = new CM.CMTime(1,requestedFrameRate);
avVideoCaptureDevice.ActiveVideoMaxFrameDuration = frameDuration;
avVideoCaptureDevice.UnlockForConfiguration();
}
This code works fine on iPhone 5 and we can record 60fps video on this device. However, on iPhone 5S, it crashes most of the time at the following line:
avVideoCaptureDevice.ActiveFormat = highSpeedFormat;
Stack trace:
0 libsystem_kernel.dylib 0x39ea41fc __pthread_kill + 8
1 libsystem_pthread.dylib 0x39f0ba4f pthread_kill + 55
2 libsystem_c.dylib 0x39e55029 abort + 73
3 EasyCaptureMonoTouch 0x0161ff8d 0x27000 + 23039885
4 EasyCaptureMonoTouch 0x0162a9fd 0x27000 + 23083517
5 libsystem_platform.dylib 0x39f06721 _sigtramp + 41
6 CoreFoundation 0x2f4c4b9b CFEqual + 231
7 CoreMedia 0x2fae1a07 CMFormatDescriptionEqual + 23
8 AVFoundation 0x2e4d7b6d -[AVCaptureDeviceFormat isEqual:] + 105
9 CoreFoundation 0x2f4cf9ef -[NSArray containsObject:] + 163
10 AVFoundation 0x2e48d69f -[AVCaptureFigVideoDevice setActiveFormat:] + 143
Sometimes, the crash occurs later with a similar stack trace (during recording, setActiveFormat is in also called) :
0 libsystem_kernel.dylib 0x39a641fc __pthread_kill + 8
1 libsystem_pthread.dylib 0x39acba4f pthread_kill + 55
2 libsystem_c.dylib 0x39a15029 abort + 73
3 EasyCaptureMonoTouch 0x017a5685 0xec000 + 23828101
4 EasyCaptureMonoTouch 0x017b00f5 0xec000 + 23871733
5 libsystem_platform.dylib 0x39ac6721 _sigtramp + 41
6 libobjc.A.dylib 0x394b59d7 realizeClass(objc_class*) + 219
7 libobjc.A.dylib 0x394b59d7 realizeClass(objc_class*) + 219
8 libobjc.A.dylib 0x394b7793 lookUpImpOrForward + 71
9 libobjc.A.dylib 0x394b0027 _class_lookupMethodAndLoadCache3 + 31
10 libobjc.A.dylib 0x394afdf7 _objc_msgSend_uncached + 23
11 CoreFoundation 0x2f084b9b CFEqual + 231
12 CoreMedia 0x2f6a1a07 CMFormatDescriptionEqual + 23
13 AVFoundation 0x2e097b6d -[AVCaptureDeviceFormat isEqual:] + 105
14 CoreFoundation 0x2f08f9ef -[NSArray containsObject:] + 163
15 AVFoundation 0x2e04d69f -[AVCaptureFigVideoDevice setActiveFormat:] + 143
16 Foundation 0x2faa5149 _NSSetObjectValueAndNotify + 93
17 AVFoundation 0x2e04d2ef -[AVCaptureFigVideoDevice _setActiveFormatAndFrameRatesForResolvedOptions:sendingFrameRatesToFig:] + 91
18 AVFoundation 0x2e06245d -[AVCaptureSession _buildAndRunGraph] + 365
19 AVFoundation 0x2e05c23b -[AVCaptureSession addInput:] + 899
We are suspecting a implementation mistake in the MonoTouch bindings or maybe a misconfiguration / 64 bits issues? Someone has an idea ?
According to:
http://forums.xamarin.com/discussion/10864/crash-when-trying-to-record-120fps-video-with-monotouch-iphone-5s#latest
it is a bug in Xamarin.iOS which will be fixed (they don't properly retain the CMFormatDescription).