Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我的BackgroundWorker仍然阻止我的UI_C#_Wpf_Dll_User Interface_Backgroundworker - Fatal编程技术网

C# 我的BackgroundWorker仍然阻止我的UI

C# 我的BackgroundWorker仍然阻止我的UI,c#,wpf,dll,user-interface,backgroundworker,C#,Wpf,Dll,User Interface,Backgroundworker,我在一个埋在.dll中的类中有一个耗时的方法,我没有它的源代码。我不想在调用此方法时阻止UI。我一直在试着用一个幕后工作者来做这件事。我从btn_Click事件处理程序调用RunWorkerAsync。当我在工作线程之外创建了dllClass实例(如下所示)时,UI将冻结,直到操作完成。该操作还阻止计时器一直滴答作响 public static dllClass dllClassInstance = new dllClass(); void worker1_DoWork(object send

我在一个埋在.dll中的类中有一个耗时的方法,我没有它的源代码。我不想在调用此方法时阻止UI。我一直在试着用一个幕后工作者来做这件事。我从btn_Click事件处理程序调用RunWorkerAsync。当我在工作线程之外创建了dllClass实例(如下所示)时,UI将冻结,直到操作完成。该操作还阻止计时器一直滴答作响

public static dllClass dllClassInstance = new dllClass();

void worker1_DoWork(object sender, DoWorkEventArgs e)
{
    dllClassInstance.TimeConsumingMethod();
}
另一方面,如果我在工作线程(如下一个代码段)内实例化该类,它将按预期工作

void worker1_DoWork(object sender, DoWorkEventArgs e)
{
    dllClass dllClassInstance = new dllClass();

    dllClassInstance.TimeConsumingMethod();
}
使用后一种方法的问题是,我需要访问该特定工作者之外的类实例,因为我必须在耗时的方法之前和之后调用其他方法。我还尝试通过e.参数将类实例传递给BackgroundWorker,但这也导致UI冻结。有人对如何在不阻塞UI的情况下调用该方法有什么建议吗

有人对如何在不阻塞UI的情况下调用该方法有什么建议吗

如果不知道
dllClass
中发生了什么,就无法确定

通常,这两种代码都不会导致UI冻结。我怀疑
dllClass
正在其构造函数中捕获当前的
SynchronizationContext
,并在
TimeConsumingMethod
中内部使用它,从而导致阻塞。如果是这种情况,您可能会在DoWork处理程序中构造类,但将其作用域改为类,这可能会起作用。但是,如果它正在捕获同步上下文,则该类可能具有线程关联性,并期望在UI线程上运行

您可以尝试在处理程序中构造实例,如下所示:

public dllClass dllClassInstance;

void worker1_DoWork(object sender, DoWorkEventArgs e)
{
    dllClassInstance = new dllClass(); // Construct here
    dllClassInstance.TimeConsumingMethod();
}
不过,正如我所说的,这可能会有其他副作用。我将验证
dllClass
没有要求它在UI线程上运行的线程关联规则

有人对如何在不阻塞UI的情况下调用该方法有什么建议吗

如果不知道
dllClass
中发生了什么,就无法确定

通常,这两种代码都不会导致UI冻结。我怀疑
dllClass
正在其构造函数中捕获当前的
SynchronizationContext
,并在
TimeConsumingMethod
中内部使用它,从而导致阻塞。如果是这种情况,您可能会在DoWork处理程序中构造类,但将其作用域改为类,这可能会起作用。但是,如果它正在捕获同步上下文,则该类可能具有线程关联性,并期望在UI线程上运行

您可以尝试在处理程序中构造实例,如下所示:

public dllClass dllClassInstance;

void worker1_DoWork(object sender, DoWorkEventArgs e)
{
    dllClassInstance = new dllClass(); // Construct here
    dllClassInstance.TimeConsumingMethod();
}

不过,正如我所说的,这可能会有其他副作用。我将验证
dllClass
没有要求它在UI线程上运行的线程关联规则。

这可能是因为您的
dllClass
。除非有人希望确保实例上的所有调用都在同一个线程中处理,否则您看到的不应该发生。如果
dllClass
在其构造函数中使用调度程序,然后
TimeConsumingMethod
通过该调度程序调用实际处理,您将看到冻结的UI。

这可能是因为您的
dllClass
。除非有人希望确保实例上的所有调用都在同一个线程中处理,否则您看到的不应该发生。如果
dllClass
在其构造函数中使用了dispatcher,然后
TimeConsumingMethod
通过该dispatcher调用实际处理,您将看到冻结的UI。

正如Reed所指出的,如果不知道该类的内部是什么,可能很难真正解决这个问题。但是,如果您有其他需要加载/准备、设置的内容,我会让您的后台工作人员类“ReportsProgress”=true,当它启动时,立即调用一个方法,该方法将根据ex:a progress 1(开始)抓取和/或准备其他设置,然后执行长过程中的其他元素,然后用99(end)这样的值报告进度,并从中进行一些清理


这听起来有帮助吗?您仍然可以将其封装到单个后台工作类中。

正如Reed所指出的,如果不知道该类的内部内容,可能很难真正解决这个问题。但是,如果您有其他需要加载/准备、设置的内容,我会让您的后台工作人员类“ReportsProgress”=true,当它启动时,立即调用一个方法,该方法将根据ex:a progress 1(开始)抓取和/或准备其他设置,然后执行长过程中的其他元素,然后用99(end)这样的值报告进度,并从中进行一些清理


这听起来有帮助吗?您仍然可以将其封装到单个后台工作类中。

我正在开发一个VB.net应用程序,在与安捷伦设备通信的Visa Com 3.0驱动程序中遇到了相同的问题。我是这样解决的:

Dim task = New Threading.Tasks.Task(Of dllClass)(Function()
                                                     Return New dllClass()
                                                 End Function)
task.Start()
task.Wait()

public static dllClass dllClassInstance = task.Result;

void worker1_DoWork(object sender, DoWorkEventArgs e)
{
    dllClassInstance.TimeConsumingMethod();
}

基本上,我在一个新线程中创建了我的dllClass实例,但立即放弃该线程并保留引用。

我正在处理一个VB.net应用程序,在与安捷伦设备通信的Visa Com 3.0驱动程序中遇到了相同的问题。我是这样解决的:

Dim task = New Threading.Tasks.Task(Of dllClass)(Function()
                                                     Return New dllClass()
                                                 End Function)
task.Start()
task.Wait()

public static dllClass dllClassInstance = task.Result;

void worker1_DoWork(object sender, DoWorkEventArgs e)
{
    dllClassInstance.TimeConsumingMethod();
}

本质上,我在一个新线程中创建了我的dllClass实例,但立即放弃该线程并保留引用。

真正的解决方案是更改TimeConsumingMethod…它正在做一些导致此问题的事情。你能给我们看看那段代码吗?@RobertLevy引用这篇文章:“…在一个埋在.dll中的类中,我没有它的源代码。”:(我会使用反射工具挖掘int