背景工作者:参数对象的子级



我正在开发一个运行平稳的 WPF 应用程序,直到我添加线程。我想通过将保存/自动保存过程放入BackgroundWorker来简化保存/自动保存过程,以便在保存 occours 时不会阻止我的 UI。

将我的应用程序视为自定义相册制作工具。 假设我的 UI 由多个图像对象组成。这些图像的源位于自定义PhotobookImageObject中,因为每个选定的图像还包含其他元数据。

相册图像对象

public class PhotobookImageObject
{
public BitmapSource source { get; set; }
public String unimportantMetadata{ get; set; }       
}

当我想保存时,我想保存完整的相册。为简单起见:

写真集

public class Photobook: INotifyPropertyChanged
{
public List<PhotobookImageObject> Photos{ get; set;}
public String otherMetaData { get; set;}
}

我的保存过程在不使用线程时有效。但是自从我在BackgroundWorker中运行它以来,我无法再访问list中的PhotobookImageObjects

现在我知道用于保存的线程不能访问来自不同线程的对象。这就是我使用自定义类将对象推送到 BackgroundWorker 线程中的原因。我在这里找到了这个解决方案:如何将列表<>列表<>传递给后台工作者?

这是准确代码:

设置工作线程:

private static BackgroundWorker saveWorker = new BackgroundWorker();

private static void saveWorkerExec(Photobook book, String Location, bool notAuto)
{
saveWorker.DoWork += doWork;
saveWorker.WorkerSupportsCancellation = true;
saveWorker.RunWorkerCompleted += (s, o) =>
{
Helper.Message("Photobook saved");
if (o.Error != null)
{
MessageBox.Show("There was an error while saving! nn" + o.Error.ToString());
}
};
BGObj obj = new BGObj
{
bk = book,
Loc = Location,
not = notAuto
};
saveWorker.RunWorkerAsync(obj);
}

我用来传输数据的自定义类:

public class BGObj
{
public Photobook bk { get; set; }
public String Loc { get; set; }
public bool not { get; set; }
}

以及BackgroundWorker应该将类接收到他自己的线程中的实际部分:

private static void doWork(object sender, DoWorkEventArgs e)
{
BGObj received = e.Argument as BGObj;
Photobook book= received.bk;
String Location = received.Loc;
bool notAuto = received.not;

//this function can not Access the books.Photos.last().source for example.
SaveProjectToContainer(book, Location, notAuto);
}

我仍在接收系统。InvalidOperationException当我尝试访问PhotobookPhotos列表中的PhotobookImageObjectBitmapSource时。

我的假设:我正在创建的BGobj引用实际的Photobook,因此其成员的数据仍然停留在错误的线程中。我到底如何确保对象的所有子成员实际上都传递到我要处理它们的线程?还是我错了,它还有其他东西?

谢谢你的时间。

由于没有人能帮助我解决这个问题,我遵循了 Theodors 的方法,并使用Async/Await切换到更现代的方法。

据我了解,这不是使操作在后台运行,而是仍然释放 UI 线程并在线程具有可用容量时"在两者之间"运行await"任务。这允许我访问 UI 元素,并且在自动保存时仍然阻止应用程序冻结一点。

如果有人需要一些提示如何解决这个问题,可以这样想:

public static void NotMain()
{
// queue following function. void Main for example would continue running after this.
await do_stuff_in_between(var object);
// Stuff after await will only happen if the function is done but UI is not blocked
Console.WriteLine("saving done");
}
public static async Task do_stuff_in_between(var object)
{
// do stuff with object or whatever you want.
}

最新更新