gpt4 book ai didi

c# - 如何使全局对象线程安全

转载 作者:行者123 更新时间:2023-11-30 17:05:44 25 4
gpt4 key购买 nike

所有,我有一个大型应用程序的并发问题,我最近使用了多线程。问题出在可以运行批处理作业的脚本处理器中

public async Task<Result> ProcessScriptAsync(
CancellationTokenSource cancelSource,
TaskScheduler uiScheduler)
{
...
// Get instance of active workbook on UI thread.
IWorkbook workbook = this.workbookView.ActiveWorkbook;
while (notFinished)
{
...
Task<bool> runScriptAsyncTask = null;
runScriptAsyncTask = Task.Factory.StartNew<bool>(() =>
{
return RunScript(ref workbook);
}, this.token,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
// Some cancellation support here...

// Run core asynchroniously.
try
{
bGenerationSuccess = await runScriptAsyncTask;
}
catch (OperationCanceledException)
{
// Handle cancellation.
}
finally
{
// Clean up.
}
}
...
}

当您考虑使用 RunScript 方法时,我的问题就来了。传递给 RunScript 的对象不是线程安全的,它是在 UI 线程上创建的。因此,我必须在 RunScript 方法中创建该对象的“深拷贝”...

private bool RunScript(ref IWorkbook workbook)
{
...
// Get a new 'shadow' workbook with which to operate on from a background thread.
IWorkbook shadowWorkbook;
if (File.Exists(workbook.FullName))
{
// This opens a workbook from disk. The Factory.GetWorkbook method is thread safe.
shadowWorkbook = SpreadsheetGear.Factory.GetWorkbook(workbook.FullName); // (##)
}
else
throw new FileNotFoundException(
"The current workbook is not saved to disk. This is a requirement. " +
"To facilitate multi-threading!");

// Do hard work here...
shadowWorkbook.WorkbookSet.GetLock();
try
{
// Do work and add worksheets to shadowWorkbook.
}
finally
{
// Reassign the UI workbook object to our new shadowWorkbook which
// has been worked on. This is fine to do as not work is actually being
// done on workbook.
workbook = shadowWorkbook;
shadowWorkbook.WorkbookSet.ReleaseLock();
}
}

我的问题出在标有 (##) 的行上。每次执行 RunScript 都会从磁盘创建一个新的 shadowWorkbook。这样做的问题是,一些工作表是在 shadowWorkbook 中创建的,随后在处理结束时被复制回 workbook。但是,每次我执行 RunScript 时,我都会从磁盘中获取工作簿,该工作簿没有在上一个循环中生成的新工作表。

我研究过使 shadowWorkbook 成为一个全局对象,但它是在 UI 线程上创建的,因此不能在我的后台操作中使用。解决此问题的一种方法是在每次创建工作表后将工作簿保存到磁盘,但创建的次数很多,而且成本很高。

有没有办法使 shadowWorkbook 全局线程安全,使我能够跨线程持久保存对我的 IWorkbook 的更改调用?

感谢您的宝贵时间。

最佳答案

嗯,我会说 this.workbookView.ActiveWorkbook 的可变资源在这种情况下需要是线程安全的。您所说的工作簿对象是在 UI 线程上创建的,因此当您分配 workbook = shadowWorkbook 时,您会在那里和任务线程中争用它。

也许声明一个同步对象,例如:

private static Object _objectLock = new Object();

并在您的 RunScript 方法(以及您修改工作簿的任何其他地方)中这样使用,以确保从不同线程串行访问资源:

lock(_objectLock)
{
workbook.AddWorkSheet();
}

在这种情况下,您不需要深度复制您的工作簿,因此消除了昂贵的调用及其产生的所有额外复杂性。

关于c# - 如何使全局对象线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16164445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com