C#线程中止
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#线程中止相关的知识,希望对你有一定的参考价值。
我使用Thread
查看等待表单,而我的主要表单正在加载Load
事件。但有时我会得到一个ThreadAbortException
,上面写着“线程被中止了”。
请帮我解决这个问题。
主窗体加载事件代码:
WaitingForm wf;
MainForm_Load(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(delegate
{
wf = new WaitingForm();
wf.ShowDialog();
}));
t.Start();
/***** Do Something *****/
if (wf != null)
wf.closeLoad();
t.Abort();
}
WaitingForm CloseLoad功能:
public void closeLoad()
{
Invoke((MethodInvoker)delegate
{
this.Close();
});
}
答案
这是我能得到的紧凑:
var waitingForm = new WaitingForm();
(new Thread (() => Application.Run(waitingForm))).Start();
HeavyWork();
waitingForm.BeginInvoke(new Action(() => waitingForm.Close()));
waitingForm
将完全响应,使用自己的消息循环在匿名线程上运行。但是,由于它在另一个线程上运行,我们需要BeginInvoke
来关闭它。
我们可以用Task
交换这个火并忘记线程:
var waitingForm = new WaitingForm();
Task.Run(() => Application.Run(waitingForm));
HeavyWork();
waitingForm.BeginInvoke((Action)(() => waitingForm.Close()));
对于使用async的替代方法,请考虑以下事项:
var source = new TaskCompletionSource<int>();
Enabled = false;
ShowWaitForm();
await HeavyWorkAsync();
Enabled = true;
source.SetResult(0);
async void ShowWaitForm()
{
var waitingForm = new WaitingForm();
waitingForm.Show(this);
await source.Task;
waitingForm.Close();
}
这次我们使用TaskCompletionSource
通知工作已经完成并且WaitingForm
可以关闭,以便我们可以等待它。
用户将会有一个不同之处:MainForm
将是可见的,甚至可以响应......我们通过禁用它并使WaitingForm
成为子形式来解决这个问题。
另一个区别是,在这种情况下,WaitingForm
没有自己的消息循环。但是,只要您使用异步方法来完成工作,它仍然会响应。
请记住,它是处理两种形式的单个线程。这可能是也可能不方便。
你总是可以回退使用Task.Run
:
var source = new TaskCompletionSource<int>();
Enabled = false;
ShowWaitForm();
await Task.Run(() => HeavyWork());
Enabled = true;
source.SetResult(0);
async void ShowWaitForm()
{
var waitingForm = new WaitingForm();
waitingForm.Show(this);
await source.Task;
waitingForm.Close();
}
请注意,在Task.Run
上使用HeavyWork
时,HeavyWork
是在另一个线程中运行的部分。现在,需要BeginInvoke
与MainForm
互动。
从那里我们可以很容易地去BackgroundWorker
:
var source = new TaskCompletionSource<int>();
Enabled = false;
ShowWaitForm();
var bg = new BackgroundWorker();
bg.DoWork += (_, __) => HeavyWork();
bg.RunWorkerCompleted += (_, __) =>
{
Enabled = true;
source.SetResult(0);
};
bg.RunWorkerAsync();
async void ShowWaitForm()
{
var waitingForm = new WaitingForm();
waitingForm.Show(this);
await source.Task;
waitingForm.Close();
}
以上是关于C#线程中止的主要内容,如果未能解决你的问题,请参考以下文章