c# - BackgroundWorker Completed 似乎没有在主线程中运行?

标签 c# outlook backgroundworker

我正在为 Outlook 编写一个插件,其中包含一些用于 API 调用的网络代码,这就是为什么我有几个扩展 BackgroundWorker 类的类,每个类都封装了一个 API 调用。 Api 调用的代码如下所示:

public class ApiLogin : BackgroundWorker
{
    private void ThisAddInStartup(object sender, EventArgs e)
    {
        this.DoWork += BgWorkerDoWork;
        this.RunWorkerCompleted += BgWorkerCompleted;
    }

    private void BgWorkerDoWork(object sender, DoWorkEventArgs e)
    {
        //Perform network call on the background thread
        var logged_in = ApiRequests.login();
        e.Result = logged_in;
    }

    //This should run in the main thread, no?
    private void BgWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var logged_in = (bool)e.Result;

        //Do stuff in main thread, hopefully..

        //Investigate if this runs in the main thread since it should block Outlook, no?
        Thread.Sleep(50000);
    }
}

对于我的 Outlook 插件,代码如下所示:

public class ThisAddin
{

    private ApiLogin _loginWorker;

    private void ThisAddInStartup(object sender, EventArgs e)
    {
       _loginWorker = new ApiLogin();
       _loginWorker.RunWorkerAsync();
    }
}

当我运行我的插件时,我预计 Outlook 会阻塞 50 秒,因为我在后台工作完成事件处理程序中有一个 Thread.Sleep(50000),但这不会发生。这对我来说意味着这段代码不在主线程中运行?我一直在徒劳地寻找解决方案,现在我想知道这里是否有人知道可能是什么问题?

最佳答案

BackgroundWorker 需要同步提供程序来确定 RunWorkerCompleted 事件在哪个线程上运行。它使用 SynchronizationContext.Current。当您的插件启动时,该属性为空的可能性非常高。因此,没有任何内容同步,并且事件在线程池线程上运行。

.NET 框架中有两种同步提供程序,分别是一种用于 Winforms 的同步提供程序和一种用于 WPF 的同步提供程序。它们需要各自的消息循环来进行线程编码(marshal),它们在 Application.Run() 方法中分配 SynchronizationContext.Current。你两者都没有。最简单的解决方案是创建一个 Winforms 窗体并调用其 ShowDialog() 方法。这本身就已经阻止了 Outlook 用户界面。向用户提供一些反馈也很好,这样她就不必猜测 Outlook 停止响应的原因。

关于c# - BackgroundWorker Completed 似乎没有在主线程中运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7360764/

相关文章:

ios - 如何通过 O365-iOS-Connect 获取/创建日历?

c# - 为什么 BackgroundWorker 的 WorkerReportsProgress 和 WorkerSupportsCancellation 的默认值是 false?

c# - 可空日期时间上的 linq

c++ - 捕获 AutoDiscoverComplete 事件

c# - 使用 LightInject 注册所有实现通用接口(interface)的类

outlook - 如何使用 ExplorerEvents_10_CloseEventHandler?

ruby-on-rails - 旧的 Sidekiq 作业永远重试。在 Sidekiq UI 上看不到

c# - 线程中的 UI 容器?

C# - 如何访问远程线程?

c# - 如何对字符串中引用的绑定(bind)数据执行操作