-1

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

我想知道当连接丢失时如何处理?谢谢

4

2 回答 2

2

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

如果这不可能,请考虑在单独的线程中执行 Web 服务数据获取。

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

于 2013-04-10T22:17:35.953 回答
1

“Excel 在使用 'XXX 加载项' 加载项时遇到了严重问题。如果您多次看到此消息,则应禁用此加载项并检查是否有可用更新。是否要禁用此加入?。”

当发生未处理的异常时,您会遇到此问题。Excel 将提示您在下次启动时禁用加载项。这可能会导致用户发布这样的帖子来修复它

当您必须支持在非管理环境中使用 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();
    }
}
于 2013-04-10T22:56:21.743 回答