Using BackgroundWorker in a WPF Application


Just sharing a small app that demonstrates the use of BackgroundWorker in WPF.

The app has two list boxes, one act as source of all the Process that needs to be processed and the other list box for the running and completed Processes.

The click of Start button starts the processing of Process.

Clicking on Cancel aborts the thread.

The XAML for the app.


<Window x:Class="BackgroundWorkerSampleApp.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="MainWindow" Height="324" Width="525" Loaded="Window_Loaded">
 <Grid Height="289">
 <ListBox Height="187" HorizontalAlignment="Left" Margin="20,52,0,0" Name="lstSource" VerticalAlignment="Top" Width="171"
 />
 <Button Content="Start" Height="41" HorizontalAlignment="Left" Margin="212,101,0,0" Name="btnStart" VerticalAlignment="Top" Width="75" Click="btnStart_Click" />
 <Button Content="Cancel" Height="42" HorizontalAlignment="Left" Margin="212,148,0,0" Name="btnCancel" VerticalAlignment="Top" Width="75" ContentStringFormat="Cancel" Click="btnCancel_Click" />
 <ListBox Height="187" HorizontalAlignment="Left" Margin="320,52,0,0" Name="lstDestination" VerticalAlignment="Top" Width="171" />
 <TextBlock Height="25" HorizontalAlignment="Left" Margin="195,252,0,0" Name="txtStatus" Text="" VerticalAlignment="Top" Width="232" />
 </Grid>
</Window>

The code behind for the app.


namespace BackgroundWorkerSampleApp
{
 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Threading;
 using System.Windows;

/// <summary>
 /// Interaction logic for MainWindow.xaml
 /// </summary>
 public partial class MainWindow : Window
 {
 #region Constants and Fields

private readonly BackgroundWorker backgroundWorker;

private readonly ObservableCollection<Process> obcProcess;

private readonly ObservableCollection<Process> obcRunningProcess;

private Thread workerThread;

#endregion

#region Constructors and Destructors

public MainWindow()
 {
 this.InitializeComponent();
 this.obcProcess = new ObservableCollection<Process>();
 this.obcRunningProcess = new ObservableCollection<Process>();
 this.lstSource.ItemsSource = this.obcProcess;
 this.lstDestination.ItemsSource = this.obcRunningProcess;
 this.lstSource.DisplayMemberPath = "ProcessName";
 this.lstDestination.DisplayMemberPath = "ProcessName";

// intialize BackgroundWorker class properties
 this.backgroundWorker = new BackgroundWorker();
 this.backgroundWorker.DoWork += this.backgroundWorker_DoWork;
 this.backgroundWorker.RunWorkerCompleted += this.backgroundWorker_RunWorkerCompleted;
 }

#endregion

#region Methods

/// <summary>
 /// Executes the process.
 /// </summary>
 /// <param name="backgroundWorker">The background worker.</param>
 private void ExecuteProcess(BackgroundWorker backgroundWorker)
 {
 if (this.obcProcess.Count > 0)
 {
 this.obcRunningProcess.Add(this.obcProcess[0]);
 backgroundWorker.RunWorkerAsync(this.obcProcess[0]);
 this.obcProcess.RemoveAt(0);
 }
 }

/// <summary>
 /// Handles the Loaded event of the Window control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
 var proc1 = new Process();
 proc1.ProcessName = "Process 1";

var proc2 = new Process();
 proc2.ProcessName = "Process 2";

var proc3 = new Process();
 proc3.ProcessName = "Process 3";

this.obcProcess.Add(proc1);
 this.obcProcess.Add(proc2);
 this.obcProcess.Add(proc3);
 }

/// <summary>
 /// Handles the DoWork event of the backgroundWorker control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
 private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
 {
 this.workerThread = Thread.CurrentThread;
 var process = e.Argument as Process;
 Thread.Sleep(5000);
 process.ProcessName = process.ProcessName + " Processed";
 }

/// <summary>
 /// Handles the RunWorkerCompleted event of the backgroundWorker control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
 private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 {
 if (e.Error != null)
 {
 MessageBox.Show(e.Error.Message);
 }
 else if (e.Cancelled)
 {
 MessageBox.Show("Cancelled");
 }
 else
 {
 if (this.obcProcess.Count > 0)
 {
 this.obcRunningProcess.Add(this.obcProcess[0]);
 this.backgroundWorker.RunWorkerAsync(this.obcProcess[0]);
 this.obcProcess.RemoveAt(0);
 }
 else
 {
 this.txtStatus.Text = "Processing Completed";
 }
 }
 }

/// <summary>
 /// Handles the Click event of the btnCancel control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
 private void btnCancel_Click(object sender, RoutedEventArgs e)
 {
 this.workerThread.Abort();
 this.txtStatus.Text = "Processing Aborted";
 }

/// <summary>
 /// Handles the Click event of the btnStart control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
 private void btnStart_Click(object sender, RoutedEventArgs e)
 {
 this.ExecuteProcess(this.backgroundWorker);
 }

#endregion
 }
}

Hope it helps.

CRM 2011 Online Fetch XML based SSRS Report and the In condition.


Hi,

Suppose I have a simple Fetch XML based report that shows all the contact’s Full name and their Email Id.

The query for it

Now let us add a like condition to it. (i.e. get all the contacts where fullname like)

The full name parameter will appear in the report.

Now comes the tricky part.

Suppose we have to find all the contact records based on the owners selected.

For owners we will have drop down field in the report.

The fetch xml query would look like below (if we specify two owners)

But here the issue is that value (tag) part would be dynamic, it has to be equal to the values selected by user in the drop down owner parameter of the report. It seems that we can’t dynamically change the Fetch Xml query in runtime for the report.

So the “In” operator won’t be of much use in case of fetch xml based report.

One way we can overcome this issue is by using Default filters.

Here users will have option of editing the filter and specifying the values for the owner which would be then passed down to the report.

This is one way I can think of getting the multiselect thing working in Fetch XML based report.

Please share and suggest your ideas for the same.

Update :-

The multivalue can be passed in the following comma separated way, so we can make use of Multiselect Report Parameter here.


<fetch mapping="logical" count="50" version="1.0">
 <entity name="contact">
 <filter>
 <condition attribute="ownerid" operator="in">
 <strong><value>48379161-2782-e111-b0d1-78e3b5178a51,48379161-2782-e111-b0d1-78e3b5178a52,A81F00C-D4E4-E011-B58C-00155D2A49C7</value></strong>
 </condition>
 </filter>
 </entity>
</fetch>

The fetch XML will have condition in the following format

<condition attribute=”ownerid” operator=”in” value=”@ActivityOwner”>

Bye.

A very helpful post on SSRS


Hi,

I have come across this post many times while developing reports in SSRS.

So just thought of sharing the link

http://www.ssw.com.au/Ssw/Standards/Rules/RulesToBetterSQLReportingServices.aspx

Bye.

 

DateTime Parameter Issue in SSRS (The date/time format is not valid)


Hi,

In one of our SSRS Report we had 2 Report Parameters, one for “From Date” and other for “To Date”.

On selecting values for them through calendar control, the value was being displayed in the proper format (mm/dd/yyyy). However the value being passed to the query was in the format (dd-mm-yyyy), because of which we were getting “The date/time format is not valid” error.

The following was the regional setting in the server.

We changed it to English (United States)

We tried running the report, but we again got the same issue.

Next we tried by changing the Language Settings of Internet Explorer.

This also didn’t solve the issue.

Finally thought of restarting the server, in case if the settings might not have got reflected properly.

After restarting the system, again tried running the report and it ran successfully J

Hope it helps.

Change log4net logging level programmatically


Hi,

We had one requirement in which we wanted to change the logging level of log4net programmatically based on the value passed.

Suppose this is how we have configured log4net in our application.


<?xml version="1.0"?>
<configuration>
 <configSections>
 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
 </configSections>
 <log4net>
 <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
 <file value="TestLog.txt"/>
 <appendToFile value="true"/>
 <rollingStyle value="Composite"/>
 <datePattern value="yyyyMMdd"/>
 <maxSizeRollBackups value="10"/>
 <maximumFileSize value="10MB"/>
 <layout type="log4net.Layout.PatternLayout">
 <conversionPattern value="[%d{yyyy-MM-dd HH:mm:ss}] [%p] [%c:%L] - %m%n"/>
 </layout>
 </appender>
 <root>
 <level value="DEBUG"/>
 <appender-ref ref="RollingLogFileAppender"/>
 </root>
 </log4net>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

The sample code for changing the log level


namespace SampleLogApp
{
 using System.Reflection;

using log4net;
 using log4net.Core;
 using log4net.Repository;
 using log4net.Repository.Hierarchy;
 using log4net.Config;

public partial class Form1 : Form
 {

 private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 private List<Person> lstPerson;

 public Form1()
 {
 InitializeComponent();
 // configure the log4net logging
 XmlConfigurator.Configure();
 }

private void btnStartLogging_Click(object sender, EventArgs e)
 {
 foreach(Person person in lstPerson)
 {
 // set the logging type depending on person
 SetLoggingLevel(person.LogType);
 logger.Debug("Debug: " + person.FullName);
 logger.Info("Info: " + person.FullName);
 logger.Warn("Warn: " + person.FullName);
 logger.Error("Error: " + person.FullName);
 }
 }

private void Form1_Load(object sender, EventArgs e)
 {
 lstPerson = new List<Person>();
 lstPerson.Add(new Person() { FullName = "Abhinav Ranjan", LogType = "Debug" });
 lstPerson.Add(new Person() { FullName = "Nirav Pancholi", LogType = "Info" });
 lstPerson.Add(new Person() { FullName = "Shobhit Bhatnagar", LogType = "Error" });
 }

/// <summary>
 /// Sets the logging level.
 /// </summary>
 /// <param name="logType">Type of the log.</param>
 private static void SetLoggingLevel(string logType)
 {
 Logger currentLogger = (Logger)logger.Logger;
 currentLogger.Level = currentLogger.Hierarchy.LevelMap[logType];
 }
 }
}

The output in TestLog.txt

[2012-04-16 00:17:27] [DEBUG] [SampleLogApp.Form1:39] – Debug: Abhinav Ranjan
[2012-04-16 00:17:27] [INFO] [SampleLogApp.Form1:40] – Info: Abhinav Ranjan
[2012-04-16 00:17:27] [WARN] [SampleLogApp.Form1:41] – Warn: Abhinav Ranjan
[2012-04-16 00:17:27] [ERROR] [SampleLogApp.Form1:42] – Error: Abhinav Ranjan
[2012-04-16 00:17:27] [INFO] [SampleLogApp.Form1:40] – Info: Nirav Pancholi
[2012-04-16 00:17:27] [WARN] [SampleLogApp.Form1:41] – Warn: Nirav Pancholi
[2012-04-16 00:17:27] [ERROR] [SampleLogApp.Form1:42] – Error: Nirav Pancholi
[2012-04-16 00:17:27] [ERROR] [SampleLogApp.Form1:42] – Error: Shobhit Bhatnagar

The helpful post

http://geekswithblogs.net/rakker/archive/2007/08/22/114900.aspx

Hope it helps.

Using EncryptedXml class for encrypting XML file in C#


Hi,

We had a requirement to encrypt a particular node and its corresponding child elements in one of our xml file. While searching for the best and the simplest way to do so, I came across these wonderful posts which make use of EncrptedXml class.

http://www.devx.com/dotnet/Article/21564/1954

http://dotnetslackers.com/articles/xml/XMLEncryption.aspx

http://blogs.msdn.com/b/shawnfa/archive/2003/11/14/57032.aspx

Hope it helps

Nishant Rana's Weblog

Everything related to Microsoft .NET Technology

Skip to content ↓