这里先给出几个连接‘
https://stackoverflow.com/questions/1862590/how-to-update-gui-with-backgroundworker
http://www.dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/whidbey/REDBITS/ndp/fx/src/CompMod/System/ComponentModel/BackgroundWorker@cs/1/BackgroundWorker@cs
https://www.codeproject.com/Articles/42103/Generic-Background-Worker
https://msdn.microsoft.com/ja-jp/library/system.componentmodel.backgroundworker(v=vs.110).aspx
原代码:
namespace
System.ComponentModel
{
using
System.ComponentModel.Design.Serialization;
using
System.Diagnostics;
using
System.Security.Permissions;
using
System.Threading;
[
SRDescription(SR.BackgroundWorker_Desc),
DefaultEvent(
"DoWork"
),
HostProtection(SharedState =
true
)
]
public
class
BackgroundWorker : Component
{
// Private statics
private
static
readonly
object
doWorkKey =
new
object
();
private
static
readonly
object
runWorkerCompletedKey =
new
object
();
private
static
readonly
object
progressChangedKey =
new
object
();
// Private instance members
private
bool
canCancelWorker =
false
;
private
bool
workerReportsProgress =
false
;
private
bool
cancellationPending =
false
;
private
bool
isRunning =
false
;
private
AsyncOperation asyncOperation =
null
;
private
readonly
WorkerThreadStartDelegate threadStart;
private
readonly
SendOrPostCallback operationCompleted;
private
readonly
SendOrPostCallback progressReporter;
public
BackgroundWorker()
{
threadStart =
new
WorkerThreadStartDelegate(WorkerThreadStart);
operationCompleted =
new
SendOrPostCallback(AsyncOperationCompleted);
progressReporter =
new
SendOrPostCallback(ProgressReporter);
}
private
void
AsyncOperationCompleted(
object
arg)
{
isRunning =
false
;
cancellationPending =
false
;
OnRunWorkerCompleted((RunWorkerCompletedEventArgs)arg);
}
[
Browsable(
false
),
SRDescription(SR.BackgroundWorker_CancellationPending)
]
public
bool
CancellationPending
{
get
{
return
cancellationPending; }
}
public
void
CancelAsync()
{
if
(!WorkerSupportsCancellation)
{
throw
new
InvalidOperationException(SR.GetString(SR.BackgroundWorker_WorkerDoesntSupportCancellation));
}
cancellationPending =
true
;
}
[
SRCategory(SR.PropertyCategoryAsynchronous),
SRDescription(SR.BackgroundWorker_DoWork)
]
public
event
DoWorkEventHandler DoWork
{
add
{
this
.Events.AddHandler(doWorkKey, value);
}
remove
{
this
.Events.RemoveHandler(doWorkKey, value);
}
}
/// <include file="docBackgroundWorker.uex" path="docs/doc[@for="BackgroundWorker.IsBusy"]/*">
[
Browsable(
false
),
SRDescription(SR.BackgroundWorker_IsBusy)
]
public
bool
IsBusy
{
get
{
return
isRunning;
}
}
/// <include file="docBackgroundWorker.uex" path="docs/doc[@for="BackgroundWorker.OnDoWork"]/*">
protected
virtual
void
OnDoWork(DoWorkEventArgs e)
{
DoWorkEventHandler handler = (DoWorkEventHandler)(Events[doWorkKey]);
if
(handler !=
null
)
{
handler(
this
, e);
}
}
/// <include file="docBackgroundWorker.uex" path="docs/doc[@for="BackgroundWorker.OnRunWorkerCompleted"]/*">
protected
virtual
void
OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
{
RunWorkerCompletedEventHandler handler = (RunWorkerCompletedEventHandler)(Events[runWorkerCompletedKey]);
if
(handler !=
null
)
{
handler(
this
, e);
}
}
protected
virtual
void
OnProgressChanged(ProgressChangedEventArgs e)
{
ProgressChangedEventHandler handler = (ProgressChangedEventHandler)(Events[progressChangedKey]);
if
(handler !=
null
)
{
handler(
this
, e);
}
}
[
SRCategory(SR.PropertyCategoryAsynchronous),
SRDescription(SR.BackgroundWorker_ProgressChanged)
]
public
event
ProgressChangedEventHandler ProgressChanged
{
add
{
this
.Events.AddHandler(progressChangedKey, value);
}
remove
{
this
.Events.RemoveHandler(progressChangedKey, value);
}
}
// Gets invoked through the AsyncOperation on the proper thread.
private
void
ProgressReporter(
object
arg)
{
OnProgressChanged((ProgressChangedEventArgs)arg);
}
// Cause progress update to be posted through current AsyncOperation.
public
void
ReportProgress(
int
percentProgress)
{
ReportProgress(percentProgress,
null
);
}
// Cause progress update to be posted through current AsyncOperation.
public
void
ReportProgress(
int
percentProgress,
object
userState)
{
if
(!WorkerReportsProgress)
{
throw
new
InvalidOperationException(SR.GetString(SR.BackgroundWorker_WorkerDoesntReportProgress));
}
ProgressChangedEventArgs args =
new
ProgressChangedEventArgs(percentProgress, userState);
if
(asyncOperation !=
null
)
{
asyncOperation.Post(progressReporter, args);
}
else
{
progressReporter(args);
}
}
public
void
RunWorkerAsync()
{
RunWorkerAsync(
null
);
}
public
void
RunWorkerAsync(
object
argument)
{
if
(isRunning)
{
throw
new
InvalidOperationException(SR.GetString(SR.BackgroundWorker_WorkerAlreadyRunning));
}
isRunning =
true
;
cancellationPending =
false
;
asyncOperation = AsyncOperationManager.CreateOperation(
null
);
threadStart.BeginInvoke(argument,
null
,
null
);
}
[
SRCategory(SR.PropertyCategoryAsynchronous),
SRDescription(SR.BackgroundWorker_RunWorkerCompleted)
]
public
event
RunWorkerCompletedEventHandler RunWorkerCompleted
{
add
{
this
.Events.AddHandler(runWorkerCompletedKey, value);
}
remove
{
this
.Events.RemoveHandler(runWorkerCompletedKey, value);
}
}
[ SRCategory(SR.PropertyCategoryAsynchronous),
SRDescription(SR.BackgroundWorker_WorkerReportsProgress),
DefaultValue(
false
)
]
public
bool
WorkerReportsProgress
{
get
{
return
workerReportsProgress; }
set
{ workerReportsProgress = value; }
}
[
SRCategory(SR.PropertyCategoryAsynchronous),
SRDescription(SR.BackgroundWorker_WorkerSupportsCancellation),
DefaultValue(
false
)
]
public
bool
WorkerSupportsCancellation
{
get
{
return
canCancelWorker; }
set
{ canCancelWorker = value; }
}
private
delegate
void
WorkerThreadStartDelegate(
object
argument);
private
void
WorkerThreadStart(
object
argument)
{
object
workerResult =
null
;
Exception error =
null
;
bool
cancelled =
false
;
try
{
DoWorkEventArgs doWorkArgs =
new
DoWorkEventArgs(argument);
OnDoWork(doWorkArgs);
if
(doWorkArgs.Cancel)
{
cancelled =
true
;
}
else
{
workerResult = doWorkArgs.Result;
}
}
catch
(Exception exception)
{
error = exception;
}
RunWorkerCompletedEventArgs e =
new
RunWorkerCompletedEventArgs(workerResult, error, cancelled);
asyncOperation.PostOperationCompleted(operationCompleted, e);
}
}
}