考虑一个对象的假设方法,为您做一些事情:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Run Code Online (Sandbox Code Playgroud)
如何等待BackgroundWorker完成?
在过去,人们尝试过:
while (_worker.IsBusy)
{
Sleep(100);
}
Run Code Online (Sandbox Code Playgroud)
但是这种死锁,因为IsBusy在RunWorkerCompleted事件处理之后才会被清除,并且在应用程序空闲之前无法处理该事件.在工人完成之前,应用程序不会闲置.(另外,这是一个繁忙的循环 - 恶心.)
其他人已添加建议将其融入:
while (_worker.IsBusy)
{
Application.DoEvents();
}
Run Code Online (Sandbox Code Playgroud)
这样做的问题是Application.DoEvents()导致当前队列中的消息被处理,这会导致重入问题(.NET不可重入).
我希望使用一些涉及事件同步对象的解决方案,其中代码等待事件 - 工作者的RunWorkerCompleted事件处理程序设置.就像是:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, …Run Code Online (Sandbox Code Playgroud)
我有一个有2个组合框的表格.我想combobox2.DataSource基于combobox1.Text和填充combobox2.Text(我假设用户已完成输入combobox1并且正在输入中combobox2).所以我有一个这样的事件处理程序combobox2:
private void combobox2_TextChanged(object sender, EventArgs e)
{
if (cmbDataSourceExtractor.IsBusy)
cmbDataSourceExtractor.CancelAsync();
var filledComboboxValues = new FilledComboboxValues{ V1 = combobox1.Text,
V2 = combobox2.Text};
cmbDataSourceExtractor.RunWorkerAsync(filledComboboxValues );
}
Run Code Online (Sandbox Code Playgroud)
至于构建DataSource是一个耗时的过程(它创建一个对数据库的请求并执行它)我决定使用BackgroundWorker在另一个进程中执行它更好.因此,当cmbDataSourceExtractor尚未完成其工作并且用户再键入一个符号时,会出现这种情况.在这种情况下,我在这一行上得到一个例外,
cmbDataSourceExtractor.RunWorkerAsync(filledComboboxValues );说明BackgroundWorker正忙,无法同时执行多个操作.
如何摆脱这种异常?
提前致谢!
我必须使用多个大的二维数组(例如1024 x 128),在我的代码的一部分中,我需要转置一些(最多12个).该过程需要相当长的时间,我试图尽可能加快速度.知道VB.NET支持多线程我在这里和那里读了不同的源,并且可以在主子例程中提出以下代码:
RunXTransposingThreads(Arr1, Arr2, Arr3, ...)
Run Code Online (Sandbox Code Playgroud)
使用BackgroundWorkers作为我的解决方案的一部分:
Private Sub RunXTransposingThreads(ParamArray ArraysToTranspose() As Array)
Dim x = CInt(ArraysToTranspose.GetLength(0)) - 1
Dim i As Integer
For i = 0 To x
Dim worker As New System.ComponentModel.BackgroundWorker
AddHandler worker.DoWork, AddressOf RunOneThread
AddHandler worker.RunWorkerCompleted, AddressOf HandleThreadCompletion
worker.RunWorkerAsync(ArraysToTranspose(i))
Next
End Sub
Private Sub RunOneThread(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
Dim Transposed(,) As Single = Array.CreateInstance(GetType(Single), 0, 0) ' I need this to be like that in order to use other …Run Code Online (Sandbox Code Playgroud) vb.net multithreading backgroundworker multidimensional-array
更新答案:等待许多不同任务完成的真正方法需要异步等待而不是后台工作人员。
#我知道有很多关于后台工作者的讨论,但我已经被四处搜索但找不到答案。
这是我的代码示例(基本逻辑,实际代码要长得多),我想知道是否有办法解决这个问题:
BackgroundWorker MCIATS1Worker = new BackgroundWorker();
private AutoResetEvent _MCIATS1WorkerResetEvent = new AutoResetEvent(false);
public MainWindow()
{
InitializeComponent();
MCIATS1Worker = new BackgroundWorker();
MCIATS1Worker.DoWork += new DoWorkEventHandler(MCIATS1Worker_DoWork);
MCIATS1Worker.WorkerReportsProgress = true;
MCIATS1Worker.WorkerSupportsCancellation = true;
MCIATS1Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MCIATS1_RunWorkerCompleted);
for (int i = 1; i <= 10; i++)
{
//some code
MCIATS1Worker.RunWorkerAsync();
_MCIATS1WorkerResetEvent.WaitOne();
}
}
Run Code Online (Sandbox Code Playgroud)
DoWork 和 runworkercompleted
void MCIATS1Worker_DoWork(object sender, DoWorkEventArgs e)
{
//do something here
}
void MCIATS1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("hello world");
_MCIATS1WorkerResetEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)
由于某些原因,在循环完成之前不会触发 MCIATS1_RunWorkerCompleted。显然,WaitOne 正在控制循环。
这是我的问题, …