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