Error: cannot convert from 'lab3.MultiSet' to 'string[]' - c#

MultiSet.cs and Form.cs
The best overloaded method match for 'string.Join(string, string[])' has some invalid arguments
Argument '2': cannot convert from 'lab3.MultiSet' to 'string[]'
namespace lab3
{
internal class MultiSet : IEnumerable<int>
{
public MultiSet()
{
}
public MultiSet(IEnumerable<int> elements)
{
if (elements == null)
throw new ArgumentNullException("elements");
foreach (int element in elements)
Add(element);
}
public MultiSet(params int[] elements)
: this((IEnumerable<int>)elements)
{
}
public IEnumerator<int> GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Add(int element)
{
if (_cardinal == _elements.Length)
{
int[] newElementsArray = new int[_elements.Length * 2];
_elements.CopyTo(newElementsArray, 0);
_elements = newElementsArray;
}
_elements[_cardinal] = element;
_cardinal++;
_lastModificationTime = DateTime.Now;
return true;
}
public int Count
{
get
{
return _cardinal;
}
}
public override string ToString()
{
return string.Format("{{ {0} }}", string.Join(", ", this));
}
private int _cardinal = 0;
private int[] _elements = new int[8];
private DateTime _lastModificationTime = DateTime.Now;
private sealed class Enumerator: IEnumerator<int>
{
public Enumerator(MultiSet set)
{
if (set == null)
throw new ArgumentNullException("set");
_set = set;
_setLastModificationTime = _set._lastModificationTime;
Reset();
}
public int Current
{
get
{
if (_index < 0 || _set._cardinal <= _index || _setLastModificationTime != _set._lastModificationTime)
throw new InvalidOperationException();
return _set._elements[_index];
}
}
void IDisposable.Dispose()
{
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public bool MoveNext()
{
if (_setLastModificationTime != _set._lastModificationTime)
throw new InvalidOperationException();
_index++;
return (_index < _set.Count);
}
public void Reset()
{
_index = -1;
}
private int _index;
private readonly MultiSet _set;
private readonly DateTime _setLastModificationTime;
}
}
}
namespace lab3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_setElementNumericUpDown.Minimum = int.MinValue;
_setElementNumericUpDown.Maximum = int.MaxValue;
_currentSetTextBox.Text = _currentSet.ToString();
}
private void _addSetButton_Click(object sender, EventArgs e)
{
_setsListBox1.Items.Add(_currentSet);
_setsListBox2.Items.Add(_currentSet);
_currentSet = new MultiSet();
_currentSetTextBox.Text = _currentSet.ToString();
}
private void _addElementToSetButton_Click(object sender, EventArgs e)
{
_currentSet.Add((int)_setElementNumericUpDown.Value);
_currentSetTextBox.Text = _currentSet.ToString();
}
private MultiSet _currentSet = new MultiSet();
}
}

Since your class is an IEnumerable< int >, have you tried making a method that returns a string[] of the items in your list?
private string[] ToStringArray()
{
if (this.Count == 0)
return null;
int i = 0;
string[] items = new string[this.Count];
IEnumerator<int> enumerator = this.GetEnumerator();
while(enumerator.MoveNext())
{
items[i] = enumerator.Current.ToString();
i++;
}
// Reset your enumerator index if needed
enumerator.Reset();
return items;
}
Then your ToString() would look like this:
public override string ToString()
{
return string.Format("{{ {0} }}", string.Join(", ", ToStringArray()));
}

Related

why is IsPresentItem giving me error in linklist?

class LinkListGen<T> where T : IComparable
{
private LinkGen<T> list;
public LinkListGen()
{
}
public string DisplayList()
{
Console.WriteLine(test);
foreach (string word in words)
{
Console.Write(word + " ");
}
Console.WriteLine();
Console.WriteLine();
}
public void AddItem(T item)
{
list = new LinkGen<T>(item);
}
public int NumberOfItems()
{
public int Count { get; }
}
public bool IsPresentItem(T item)
{
Link temp = list;
bool result = false;
while (temp != null)
{
if (temp.Data == item)
{
result = true;
break;
}
else
{
temp = temp.Next;
}
}
return result;
}
}
I have been trying to make a generic link list but I am not sure why it is giving me an error. The error is coming from the IsPresentItem. Also I'm not sure when I need to add to the linkListGen. thank you for your time
You've got missing closing brace on the NumberOfItems method because you've declared the Count property within it:
public int NumberOfItems()
{
public int Count { get; }
}
It should be:
public int NumberOfItems()
{
//Do Something
}
public int Count { get; }
The whole class should then look like this:
class LinkListGen<T> where T : IComparable
{
private LinkGen<T> list;
public LinkListGen()
{
}
public string DisplayList()
{
Console.WriteLine(test);
foreach (string word in words)
{
Console.Write(word + " ");
}
Console.WriteLine();
Console.WriteLine();
}
public void AddItem(T item)
{
list = new LinkGen<T>(item);
}
public int NumberOfItems()
{
//Do Something
}
public int Count { get; }
public bool IsPresentItem(T item)
{
Link temp = list;
bool result = false;
while (temp != null)
{
if (temp.Data == item)
{
result = true;
break;
}
else
{
temp = temp.Next;
}
}
return result;
}
}

C# Runtime Error: InvalidCastException with Generic Class Instance

I'm a java developer and new to C#, I'm stuck with InvalidCastException on the following code below.
I have implemented a Queue, based on a custom Doubly Linked List implementation. Both implementations are generic, and thus, on the test code, I want to use a generic print method.
The test code below is just working fine;
using System;
using System.Collections.Generic;
namespace Queue01
{
public class TestQueue
{
public static void Main(string[] args)
{
Queue<int> queue = new Queue<int>();
queue.Enqueue(4);
queue.Enqueue(5);
queue.Enqueue(6);
Console.WriteLine("*****");
PrintQueue(queue);
Console.WriteLine("*****");
int first = queue.Dequeue();
Console.WriteLine("Enqueued value : " + first);
Console.WriteLine("*****");
PrintQueue(queue);
}
public static void PrintQueue(object queue)
{
Queue<int> q = (Queue<int>)queue;
foreach (object i in q)
{
Console.WriteLine(i);
}
}
}
}
However, I want to make the PrintQueue static method working for all types, thus I've changed the method code as below;
public static void PrintQueue(object queue)
{
Queue<object> q = (Queue<object>)queue;
foreach (object i in q)
{
Console.WriteLine(i);
}
}
The whole test code which is not working is as below;
using System;
using System.Collections.Generic;
namespace Queue01
{
public class TestQueue
{
public static void Main(string[] args)
{
Queue<int> queue = new Queue<int>();
queue.Enqueue(4);
queue.Enqueue(5);
queue.Enqueue(6);
Console.WriteLine("*****");
PrintQueue(queue);
Console.WriteLine("*****");
int first = queue.Dequeue();
Console.WriteLine("Enqueued value : " + first);
Console.WriteLine("*****");
PrintQueue(queue);
}
public static void PrintQueue(object queue)
{
Queue<object> q = (Queue<object>)queue;
foreach (object i in q)
{
Console.WriteLine(i);
}
}
}
}
And then I'm stuck with the InvalidCastException. Where is the problem and how can I fix this exception and what is the best practice to make this code generic?
On java, Object is the base, root class of every class instance. Thus, I've passed the stack instance as an object to the method, assuming that it won't be a problem because int, the alias for Int32 also extended from the Object.
Here down below, I am adding the whole rest files that I've used for compiling the test code above;
1) Here is the DoublyLinkedListNode class that I used in Doubly Linked List implemetation;
using System;
using System.Collections.Generic;
namespace Queue01
{
public class DoublyLinkedListNode<T>
{
// Fields
public T Value { get; set; }
public DoublyLinkedListNode<T> Previous { get; set; }
public DoublyLinkedListNode<T> Next { get; set; }
public DoublyLinkedListNode(T value)
{
Value = value;
}
}
}
2) Here is my DoublyLinkedList class which implements a doubly linked list for the queue implementation I am going to use;
using System;
using System.Collections.Generic;
namespace Queue01
{
public class DoublyLinkedList<T> : ICollection<T>
{
#region Fields
public DoublyLinkedListNode<T> Head { get; private set; }
public DoublyLinkedListNode<T> Tail { get; private set; }
#endregion
#region Constructor
#endregion
#region Add
public void AddFirst(T value)
{
AddFirst(new DoublyLinkedListNode<T>(value));
}
public void AddFirst(DoublyLinkedListNode<T> node)
{
DoublyLinkedListNode<T> temp = Head;
Head = node;
Head.Next = temp;
//if(Count == 0)
if (Empty)
{
Tail = Head;
}
else
{
temp.Previous = Head;
}
Count++;
}
public void AddLast(T value)
{
AddLast(new DoublyLinkedListNode<T>(value));
}
public void AddLast(DoublyLinkedListNode<T> node)
{
//if (Count == 0)
if (Empty)
{
Head = node;
}
else
{
Tail.Next = node;
node.Previous = Tail;
}
Tail = node;
Count++;
}
#endregion
#region Remove
public void RemoveFirst()
{
//if (Count != 0)
if (!Empty)
{
Head = Head.Next;
Count--;
if (Count == 0)
{
Tail = null;
}
else
{
Head.Previous = null;
}
}
}
public void RemoveLast()
{
//if (Count != 0)
if (!Empty)
{
if (Count == 1)
{
Head = null;
Tail = null;
}
else
{
Tail.Previous.Next = null;
Tail = Tail.Previous;
}
Count--;
}
}
#endregion
#region ICollection
public int Count
{
get;
private set;
}
public void Add(T item)
{
AddFirst(item);
}
public bool Contains(T item)
{
DoublyLinkedListNode<T> current = Head;
while (current != null)
{
if (current.Value.Equals(item))
{
return true;
}
current = current.Next;
}
return false;
}
public void CopyTo(T[] array, int arrayIndex)
{
DoublyLinkedListNode<T> current = Head;
while (current != null)
{
array[arrayIndex++] = current.Value;
current = current.Next;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public bool Remove(T item)
{
DoublyLinkedListNode<T> previous = null;
DoublyLinkedListNode<T> current = Head;
while (current != null)
{
if (current.Value.Equals(item))
{
if (previous != null)
{
previous.Next = current.Next;
if (current.Next == null)
{
Tail = previous;
}
else
{
current.Next.Previous = previous;
}
Count--;
}
else
{
RemoveFirst();
}
return true;
}
previous = current;
current = current.Next;
}
return false;
}
public void Clear()
{
Head = null;
Tail = null;
Count = 0;
}
//System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator()
public IEnumerator<T> GetEnumerator()
{
DoublyLinkedListNode<T> current = Head;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
//return ((System.Collections.Generic.IEnumerable<T>)this).GetEnumerator();
return this.GetEnumerator();
}
#endregion
#region helper
public void PrintEnumerable()
{
IEnumerator<T> e = this.GetEnumerator();
while (e.MoveNext())
{
T val = e.Current;
Console.WriteLine("Value: " + val);
}
}
public void PrintReverse()
{
for (DoublyLinkedListNode<T> node = Tail; node != null; node = node.Previous)
{
Console.WriteLine(node.Value);
}
}
public bool isEmpty()
{
if (Count == 0)
{
return true;
}
return false;
}
public bool Empty { get { return isEmpty(); } }
public DoublyLinkedListNode<T> First { get { return this.Head; } }
public DoublyLinkedListNode<T> Last { get { return this.Tail; } }
#endregion
}
}
3) And this is my Queue implementation based on doubly linked list implemetation that I've used above;
using System;
using System.Collections.Generic;
namespace Queue01
{
public class Queue<T> : System.Collections.Generic.IEnumerable<T>
{
DoublyLinkedList<T> _items = new DoublyLinkedList<T>();
LinkedList<T> hede = new LinkedList<T>();
public void Enqueue(T item)
{
_items.AddLast(item);
}
public T Dequeue()
{
if(_items.Count == 0)
{
throw new InvalidOperationException("The queue is empty.");
}
T value = _items.First.Value;
_items.RemoveFirst();
return value;
}
public IEnumerator<T> GetEnumerator()
{
return this._items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
Fundamentally, you shouldn't try to make PrintQueue work for every object - you should try to make it work for any Queue<T>... and the simplest way of doing that is to make it generic:
public static void PrintQueue<T>(Queue<T> queue)
{
foreach (T item in queue)
{
Console.WriteLine(item);
}
}
Or you could be more general and accept an IEnumerable<T>:
public static void PrintSequence<T>(IEnumerable<T> queue)
{
foreach (T item in queue)
{
Console.WriteLine(item);
}
}
Your original code is failing because a Queue<int> isn't a Queue<object>... in fact, because Queue<T> isn't covariant in T, you can't convert Queue<string> to Queue<object>... but IEnumerable<T> is covariant, so:
Queue<string> stringQueue = new Queue<string>();
...
PrintSequence<object>(stringQueue);
... would be okay.
What about change PrintQueue method. Just like this:
public static void PrintQueue<T>(object queue)
{
var q = (Queue<T>)queue;
foreach (var i in q)
Console.WriteLine(i);
}
and use it like this:
PrintQueue<int>(queue);
change your code like this:
public static void PrintQueue(dynamic queue)
{
foreach (var i in queue)
{
Console.WriteLine(i);
}
}

How do you enable Sorting in a DataGridView with an assigned DataSource?

On several recommendations, I started to assign a DataSource to my DataGridView instead of using DataGridView.Rows.Add(...). This is convenient since my data source is already a big list which doesn't change (much). However, when I use the DataSource assignment, it becomes impossible to sort the columns.
class MyGridView : DataGridView
{
private List<Person> m_personList;
private class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string first, string last)
{
FirstName = first;
LastName = last;
}
}
public MyGridView()
{
/* ...initialise stuff... */
m_personList.Add(new Person("Kate", "Smith"));
m_personList.Add(new Person("Bill", "Davids"));
m_personList.Add(new Person("Ann", "Roth"));
this.DataSource = m_personList;
}
}
I also tried to replace List<Person> by BindingList<Person> and by BindingSource, but none of that seems to matter. I also tried adding a custom sorter:
this.SortCompare += MyGridView_SortCompare;
private void MyGridView_SortCompare(object sender, EventArgs e)
{
/* ...Compare method...*/
}
but the thing doesn't even get called. Is there some other way to enable sorting with a DataSource?
Note: Note that my DataSource is not (necessarily) an SQL one, but just any List.
You need to coerce your datasource into a list that supports sorting (IBindingList and IBindingListView), and then it will work out of the box. There are lots of examples on the web, this is the one I've used in the past:
// usage:
// var sortableList = new SortableList(m_personList);
// dgv.DataSource = m_sortableList;
/// <summary>
/// Suitable for binding to DataGridView when column sorting is required
/// </summary>
/// <typeparam name="T"></typeparam>
public class SortableList<T> : BindingList<T>, IBindingListView
{
private PropertyComparerCollection<T> sorts;
public SortableList()
{
}
public SortableList(IEnumerable<T> initialList)
{
foreach (T item in initialList)
{
this.Add(item);
}
}
public SortableList<T> ApplyFilter(Func<T, bool> func)
{
SortableList<T> newList = new SortableList<T>();
foreach (var item in this.Where(func))
{
newList.Add(item);
}
return newList;
}
protected override bool IsSortedCore
{
get { return this.sorts != null; }
}
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override ListSortDirection SortDirectionCore
{
get
{
return this.sorts == null
? ListSortDirection.Ascending
: this.sorts.PrimaryDirection;
}
}
protected override PropertyDescriptor SortPropertyCore
{
get
{
return this.sorts == null ? null : this.sorts.PrimaryProperty;
}
}
public void ApplySort(ListSortDescriptionCollection
sortCollection)
{
bool oldRaise = RaiseListChangedEvents;
RaiseListChangedEvents = false;
try
{
PropertyComparerCollection<T> tmp
= new PropertyComparerCollection<T>(sortCollection);
List<T> items = new List<T>(this);
items.Sort(tmp);
int index = 0;
foreach (T item in items)
{
SetItem(index++, item);
}
this.sorts = tmp;
}
finally
{
RaiseListChangedEvents = oldRaise;
ResetBindings();
}
}
public bool Exists(Predicate<T> func)
{
return new List<T>(this).Exists(func);
}
string IBindingListView.Filter
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
void IBindingListView.RemoveFilter()
{
throw new NotImplementedException();
}
ListSortDescriptionCollection IBindingListView.SortDescriptions
{
get { return (this.sorts == null ? null : this.sorts.Sorts); }
}
bool IBindingListView.SupportsAdvancedSorting
{
get { return true; }
}
bool IBindingListView.SupportsFiltering
{
get { return false; }
}
protected override void RemoveSortCore()
{
this.sorts = null;
}
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
ListSortDescription[] arr = { new ListSortDescription(prop, direction) };
ApplySort(new ListSortDescriptionCollection(arr));
}
}
public class PropertyComparerCollection<T> : IComparer<T>
{
private readonly PropertyComparer<T>[] comparers;
private readonly ListSortDescriptionCollection sorts;
public PropertyComparerCollection(ListSortDescriptionCollection
sorts)
{
if (sorts == null)
{
throw new ArgumentNullException("sorts");
}
this.sorts = sorts;
List<PropertyComparer<T>> list = new
List<PropertyComparer<T>>();
foreach (ListSortDescription item in sorts)
{
list.Add(new PropertyComparer<T>(item.PropertyDescriptor,
item.SortDirection == ListSortDirection.Descending));
}
this.comparers = list.ToArray();
}
public ListSortDescriptionCollection Sorts
{
get { return this.sorts; }
}
public PropertyDescriptor PrimaryProperty
{
get
{
return this.comparers.Length == 0
? null
: this.comparers[0].Property;
}
}
public ListSortDirection PrimaryDirection
{
get
{
return this.comparers.Length == 0
? ListSortDirection.Ascending
: this.comparers[0].Descending
? ListSortDirection.Descending
: ListSortDirection.Ascending;
}
}
int IComparer<T>.Compare(T x, T y)
{
int result = 0;
foreach (PropertyComparer<T> t in this.comparers)
{
result = t.Compare(x, y);
if (result != 0)
{
break;
}
}
return result;
}
}
public class PropertyComparer<T> : IComparer<T>
{
private readonly bool descending;
private readonly PropertyDescriptor property;
public PropertyComparer(PropertyDescriptor property, bool descending)
{
if (property == null)
{
throw new ArgumentNullException("property");
}
this.descending = descending;
this.property = property;
}
public bool Descending
{
get { return this.descending; }
}
public PropertyDescriptor Property
{
get { return this.property; }
}
public int Compare(T x, T y)
{
int value = Comparer.Default.Compare(this.property.GetValue(x),
this.property.GetValue(y));
return this.descending ? -value : value;
}
}
An alternate is to convert your List into DataTable and then bind that DataTable to the DataGridView through BindingSource. This way your DataGridView will inherit the sort options available with the DataTable.
For converting a list to DataTable, refer the article:
How to fill a datatable with List<T>

.Net Immutable Collections with WPF DataGrid

Has anybody found a nice pattern for binding ImmutableCollections ( from the MS BCL ) to a WPF DataGrid? To represent mutablility of an immutable structure I would wrap it with ISubject to track changes and provide new versions to the datagrid.
ISubject<ImmutableList<T>> <--(binding)--> DataGrid
The DataGrid obviously needs a mutable collection such as ObservableCollection directly under it so perhaps the problem can be reduced to
ISubject<ImmutableList<T>> <-----> ObservableCollection<T>
Any suggestions?
ObservableCollection
Here is a partial solution.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Immutable;
using System.Collections.Specialized;
using ReactiveUI;
namespace ReactiveUI.Ext
{
public class ImmutableListToReactive<T> : ReactiveObject, ICollection<T>, INotifyCollectionChanged, IDisposable, IList<T>
where T : class, Immutable
{
private ISubject<ImmutableList<T>> _Source;
ImmutableList<T> _Current;
public ImmutableList<T> Current
{
get { return _Current; }
set { this.RaiseAndSetIfChanged(ref _Current, value); }
}
public void Dispose()
{
_Subscription.Dispose();
}
public ImmutableListToReactive( ISubject<ImmutableList<T>> source )
{
_Source = source;
_Subscription = source.Subscribe(newVersion =>
{
if ( !rebound )
{
_Current = newVersion;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
});
}
private void OnNext( ImmutableList<T> list )
{
rebound = true;
_Current = list;
try
{
_Source.OnNext(list);
}
finally
{
rebound = false;
}
}
public void Add( T item )
{
OnNext(_Current.Add(item));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new List<T>(){item}, Current.Count - 1));
}
public void Clear()
{
OnNext(_Current.Clear());
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
public bool Contains( T item )
{
return _Current.Contains(item);
}
public void CopyTo( T[] array, int arrayIndex )
{
_Current.CopyTo(array, arrayIndex);
}
public int Count
{
get { return _Current.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove( T item )
{
var idx = _Current.IndexOf(item);
var next = _Current.Remove(item);
if ( next == _Current )
{
return false;
}
else
{
OnNext(next);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, idx));
return true;
}
}
public IEnumerator<T> GetEnumerator()
{
return _Current.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _Current.GetEnumerator();
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
private IDisposable _Subscription;
bool rebound = false;
protected virtual void OnCollectionChanged( NotifyCollectionChangedEventArgs e )
{
if ( !rebound )
{
rebound = true;
if ( CollectionChanged != null )
{
CollectionChanged(this, e);
}
rebound = false;
}
}
public int IndexOf( T item )
{
return _Current.IndexOf(item);
}
public void Insert( int index, T item )
{
OnNext(_Current.Insert(index, item));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
public void RemoveAt( int index )
{
var itemToBeRemoved = _Current[index];
OnNext(_Current.RemoveAt(index));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, itemToBeRemoved, index));
}
public T this[int index]
{
get
{
return _Current[index];
}
set
{
OnNext(_Current.SetItem(index, value));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, value, index));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value, index));
}
}
}
}
and a test case
using FluentAssertions;
using ReactiveUI.Subjects;
using System;
using System.Collections.Immutable;
using System.Collections.Specialized;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using Xunit;
namespace ReactiveUI.Ext.Spec
{
public class Data : Immutable
{
public int A { get; private set; }
public int B { get; private set; }
public bool Equals(Data other){
return A == other.A && B == other.B;
}
public bool Equals(object o){
Data other = o as Data;
if ( other == null )
{
return false;
}
return this.Equals(other);
}
public static bool operator ==( Data a, Data b )
{
return a.Equals(b);
}
public static bool operator !=( Data a, Data b )
{
return !a.Equals(b);
}
public Data( int a, int b )
{
A = a;
B = b;
}
}
public class DataMutable : ReactiveObject, IDisposable
{
int _A;
public int A
{
get { return _A; }
set { this.RaiseAndSetIfChanged(ref _A, value); }
}
int _B;
public int B
{
get { return _B; }
set { this.RaiseAndSetIfChanged(ref _B, value); }
}
IDisposable _Subscriptions;
public DataMutable( ILens<Data> dataLens )
{
_Subscriptions = new CompositeDisposable();
var d0 = dataLens.Focus(p => p.A).TwoWayBindTo(this, p => p.A);
var d1 = dataLens.Focus(p => p.B).TwoWayBindTo(this, p => p.B);
_Subscriptions = new CompositeDisposable(d0, d1);
}
public void Dispose()
{
_Subscriptions.Dispose();
}
}
public class ImmutableListToReactiveSpec : ReactiveObject
{
ImmutableList<Data> _Fixture;
public ImmutableList<Data> Fixture
{
get { return _Fixture; }
set { this.RaiseAndSetIfChanged(ref _Fixture, value); }
}
[Fact]
public void ReactiveListSux()
{
var a = new ReactiveList<int>();
var b = a.CreateDerivedCollection(x => x);
a.Add(10);
b.Count.Should().Be(1);
}
[Fact]
public void ShouldWork()
{
Fixture = ImmutableList<Data>.Empty;
// Convert an INPC property to a subject
ISubject<ImmutableList<Data>> s = this.PropertySubject(p => p.Fixture);
var MutableList = new ImmutableListToReactive<Data>(s);
var DerivedList = MutableList.CreateDerivedCollection(x => x);
Fixture = Fixture.Add(new Data(10, 20));
DerivedList.ShouldAllBeEquivalentTo(Fixture);
Fixture = Fixture.Add(new Data(11, 21));
DerivedList.ShouldAllBeEquivalentTo(Fixture);
Fixture = Fixture.Add(new Data(12, 22));
MutableList.Count.Should().Be(3);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
MutableList.Add(new Data(33, 88));
MutableList.Count.Should().Be(4);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
MutableList[1] = new Data(99, 21);
MutableList.Count.Should().Be(4);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
var itemAtOne = MutableList[1];
MutableList.RemoveAt(1);
MutableList.Should().NotContain(itemAtOne);
MutableList.Count.Should().Be(3);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
var i = new Data(78, 32);
MutableList.Insert(0, i);
DerivedList[0].Should().Be(i);
MutableList.Count.Should().Be(4);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
var j = new Data(18, 22);
MutableList.Insert(3, j);
DerivedList[3].Should().Be(j);
MutableList.Count.Should().Be(5);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
var k = new Data(18, 22);
MutableList.Add(k);
DerivedList[DerivedList.Count-1].Should().Be(k);
MutableList.Count.Should().Be(6);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
MutableList.Remove(i);
DerivedList[DerivedList.Count-1].Should().Be(k);
MutableList.Count.Should().Be(5);
DerivedList.ShouldAllBeEquivalentTo(Fixture);
MutableList.ShouldAllBeEquivalentTo(Fixture);
}
}
}

MongoDb Insert speed very slow, single threaded inserts and multiple

I have written some test for repository I have wrote.
public interface IEntity<T> {
T Id { get; set; }
}
public abstract class Entity<TEntity> : IEntity<TEntity> {
[BsonId]
public TEntity Id { get; set; }
public override string ToString() {
return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
});
}
}
public interface IMongoRepository<TEntity, TE> : IQueryable<TEntity> where TEntity : IEntity<TE> {
string ConnectionString { get; set; }
bool Remove<T>(TEntity entity);
bool Save<T>(TEntity entity);
bool Update<T>(TEntity entity);
}
public sealed class MongoRepository<TEntity, TU> : IMongoRepository<TEntity, TU>
where TEntity : Entity<TU> {
public MongoCollection<TEntity> Collection {
get {
var client = new MongoClient(ConnectionString);
var server = client.GetServer();
var db = server.GetDatabase("mykantina");
return db.GetCollection<TEntity>(typeof (TEntity).Name.Pluralize());
}
}
private IQueryable<TEntity> Queryable {
get { return Collection.FindAll().AsQueryable(); }
}
#region IRepository<T,U> Implementation
public string ConnectionString { get; set; }
public bool Remove<T>(TEntity entity) {
try {
var e = entity as Entity<TU>;
if (e == null) return false;
WriteConcernResult resultConcern = Collection.Remove(Query.EQ("_id", e.Id.ToBson()));
return true;
}
catch (Exception e) {
return false;
}
}
public bool Save<T>(TEntity entity) {
try {
WriteConcernResult resultConcern = Collection.Save(entity);
return true;
}
catch (Exception e) {
return false;
}
}
public bool Update<T>(TEntity entity) {
throw new NotImplementedException();
}
#endregion
#region IQueryable<T> Implementation
public IEnumerator<TEntity> GetEnumerator() {
return Queryable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return Queryable.GetEnumerator();
}
public Type ElementType {
get { return Queryable.ElementType; }
}
public Expression Expression {
get { return Queryable.Expression; }
}
public IQueryProvider Provider {
get { return Queryable.Provider; }
}
#endregion
}
Here are the tests:
[Test]
public void LinearInsertsToMongoDb() {
Stopwatch total = Stopwatch.StartNew();
for (int i = 0; i <= 100000; i++) {
Stopwatch sw = Stopwatch.StartNew();
var isOk = _repository.Save<Widget>(new Widget {
Name = "Calendar" + i
});
sw.Stop();
Trace.WriteLine(string.Format("Took to insert {0}ms - item {1}", sw.ElapsedMilliseconds, i));
}
Trace.WriteLine(string.Format("================================================================"));
total.Stop();
Trace.WriteLine(string.Format("Total = {0}ms", total.ElapsedMilliseconds));
}
Time result: Total = 212398ms
private static object _sync = new object();
[Test]
public void ConcurrentInsertsToMongoDb() {
Stopwatch total = Stopwatch.StartNew();
var waitHandlers = new List<WaitHandle>();
for (int i = 0; i < 50; i++) {
var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
waitHandlers.Add(threadFinish);
var thread = new Thread(() => {
RunMongoThread();
threadFinish.Set();
});
thread.Start();
}
WaitHandle.WaitAll(waitHandles: waitHandlers.ToArray());
Trace.WriteLine(string.Format("================================================================"));
total.Stop();
Trace.WriteLine(string.Format("Total = {0}ms", total.ElapsedMilliseconds));
}
private static void RunMongoThread() {
for (var i = 0; i < 300; i++) {
bool isLocked = false;
try {
Monitor.Enter(_sync, ref isLocked);
var widget = new Widget {
Name = "Calendar" + i
};
var isOk = _repository.Save<Widget>(widget);
Trace.WriteLine(string.Format("Object: {0} - Thread {1}", widget, Thread.CurrentThread.ManagedThreadId));
}
finally {
if(isLocked)
Monitor.Exit(_sync);
}
}
}
Time result: Total 31303ms
The question what I'm doing wrong and why it's so slow?

Categories

Resources