Background
I am writing some software that does the following:
- The user clicks on "start".
- A task is started that performs some work and launches events to update the GUI.
- An observable consumes the events from the task, and prints data to a rich-text-box in the GUI.
Everything works alright when I click on "START" the first time, but not after that. The first time I click on start, I get an output that looks like:
This looks alright, nothing wrong here. However, when I click on START the second time I get the following output.
Now, I believe I know why this might be happening. From what I can tell, my observer never unsubscribed from the first time I clicked on START and thus everything gets printed twice. When clicking on the start button, here is what happens:
/// <summary>
/// Starts the test.
/// </summary>
/// <param name="sender">The "start" button.</param>
/// <param name="e">Clicking on the "start" button.</param>
private void button_go_Click(object sender, RoutedEventArgs e)
{
var uiContext = SynchronizationContext.Current;
var results = Observable.FromEventPattern<TestResultHandler, TestResultArgs>(
handler => (s, a) => handler(s, a),
handler => this.myTest.Results += handler,
handler => this.myTest.Results -= handler)
.ObserveOn(uiContext)
.Subscribe(x => this.richTextBox_testResults.Document.Blocks.Add(new Paragraph(new Run(x.EventArgs.Results))));
// start running the test
this.runningTest = new Task(() => { this.myTest.Run(); });
this.runningTest.Start();
// block on purpose, wait for the task to finish
this.runningTest.Wait();
}
I am new to reactive extensions in .NET (have been using it for less than one hour). I am essentially using one of Stephen Cleary's examples from the Concurrency in C# cookbook in order to get started here. Despite all of this, I believe I sort of know what the problem is...
Proposed Plan
If I could just unsubscribe from the observable, then I think that this problem would go away. I think it's a little more complicated that that though, based on the reactive patterns used at ReactiveX.io it sounds like I should actually be smartly observing the task only for the during in which it actually exists then unsubscribing naturally. This is as far as I have come with debugging this problem, and I am not 100% sure that this unsubscribing thing would actually fix the problem.
Question
Is there some way to unsubscribe from the observable? Or, is there a way that I could observe my task only for the duration that it exists?