丢失的网络连接导致Excel崩溃

时间:2013-04-10 22:08:17

标签: c# excel connection add-in

我的Excel AddIn是用NetOffice,ExcelDNA,C#编写的 它调用Web服务来获取数据。获取大量数据需要一段时间。 在数据获取过程中,如果网络连接丢失,则Excel将挂起,显示为“无响应”。现在,如果我尝试关闭Excel,它会要求您关闭或调试。我只是关闭它。 然后,当我重新启动Excel时,会出现一个恼人的消息框 “Excel遇到了'商品加载项'加载项的严重问题。如果您多次看过此邮件,则应禁用此加载项并检查是否有可用的更新。是否要禁用此功能附加?“。

我想知道如何在连接失败时处理这种情况?谢谢

2 个答案:

答案 0 :(得分:2)

如果可能,请异步进行Web服务调用。大多数WS将提供您可以进行的调用的异步版本和非异步版本。

如果无法做到这一点,请考虑在单独的线程中执行Web服务数据提取。

在这两种情况下,您应该放置一些管道代码以在一段时间后终止该作业,并且可能有一些方法通知用户并非一切都很好。

答案 1 :(得分:1)

  

" Excel遇到了一个严重的问题,即' XXX加载项'加入。如果   你多次看过这个消息,你应该禁用它   加载项并检查是否有可用的更新。你想要_____吗   禁用此加载项?。"

发生未处理的异常时会出现此问题。 Excel将提示您下次启动时禁用加载项。这可以引导用户发布this to fix it等帖子。

当您必须在非管理员环境中使用Citrix支持客户端时,痛苦更加严重。要解决Excel想要加载加载项的问题,您必须添加一个全局异常处理程序,以便异常不会返回到Excel以避免提示用户禁用加载项。

public YouAddInCtrl()
{
    InitializeComponent();
    // Add the event handler for handling UI thread exceptions to the event.
    System.Windows.Forms.Application.ThreadException += ApplicationThreadException;
    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException += ApplicationUnhandledException;   
}

private void ApplicationThreadException(object sender, ThreadExceptionEventArgs e)
{
    addInManager.TopLevelExceptionHandler(e.Exception);
}

private void ApplicationUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    addInManager.TopLevelExceptionHandler((Exception)e.ExceptionObject);
}


// Any exceptions returned to Excel will cause the Addin to be disabled
// So we must swallow them here.
internal void TopLevelExceptionHandler(Exception ex)
{
    var e = new NotificationEventArgs(NotificationEventArgs.NotificationEnum.TopLevelException);
    if (NotifyEventTopLevelException != null)
    {
        if (NotifyEventTopLevelException(ex,e))
        {
            System.Diagnostics.Process.Start("mailto:Support@XYZ.com%3e?subject=XYZ%202%20PROD%20Environment%20Problem&body=Hi,%0A%0AIssue:%0A%0ASteps%20to%20Reproduce:"); 
        }
    }

    LogExceptions(ex);
}

我还建议您在不同的线程上运行WebService请求,例如:

BackgroundWorker1.WorkerReportsProgress = true;
BackgroundWorker1.WorkerSupportsCancellation = true;
BackgroundWorker1.DoWork += DoWorkExecuteQuery;
BackgroundWorker1.RunWorkerCompleted += RunWorkerCompletedExecuteQuery;


private bool QueryData()
{
    var thinkProgBar = new ThinkingProgressBar();
    thinkProgBar.ShowCancelLink(true);
    thinkProgBar.SetThinkingBar(true);
    BackgroundWorker1.RunWorkerAsync(thinkProgBar);
    thinkProgBar.ShowDialog();
    if (thinkProgBar.Tag != null && thinkProgBar.Tag.ToString() == "Cancelled")
    {
        CancelGetDataByFilters();
        thinkProgBar.SetThinkingBar(false);
        return false;
    }
    thinkProgBar.SetThinkingBar(false);
    return true;
}

private void DoWorkExecuteQuery(object sender, DoWorkEventArgs e)
{
    dtQueryData = null;
    e.Result = e.Argument;
    ((ThinkingProgressBar)e.Result).SetThinkingBar(true);
    dtQueryData = WEBSERVICE.GetData();  //CALL YOUR WEBSERVICE HERE
}

private void RunWorkerCompletedExecuteQuery(object sender, RunWorkerCompletedEventArgs e)
{
    var dlg = e.Result as ThinkingProgressBar;
    if (dlg != null) {
        ((ThinkingProgressBar)e.Result).SetThinkingBar(false);
        dlg.Close();
    }
}

这是ThinkingProgress栏:

public partial class ThinkingProgressBar : Form
{
    private System.DateTime startTime = DateTime.Now;
    public ThinkingProgressBar()
    {
        InitializeComponent();
    }

    private void lblClose_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
    {
        this.Tag = "Cancelled";
        this.Hide();
    }
    public void ShowCancelLink(bool show)
    {
        lblClose.Visible = show;
    }

    public void SetThinkingBar(bool on)
    {
        if (on)
        {
            lblTime.Text = "0:00:00";
            startTime = DateTime.Now;
            timer1.Enabled = true;
            timer1.Start();
        }
        else
        {
            timer1.Enabled = false;
            timer1.Stop();
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        var diff = new TimeSpan();
        diff = DateTime.Now.Subtract(startTime);
        lblTime.Text = diff.Hours + ":" + diff.Minutes.ToString("00") + ":" + diff.Seconds.ToString("00");
        lblTime.Invalidate();
    }
}