私はMSDNでもあなたの質問にこの応答を掲載しました。
これは、現在の操作の途中でキャンセルして再び開始すると、ReportViewerの内部非同期レンダリングと関係があります。レポートを読み込んだ後、すぐに表示モードを印刷レイアウトに設定することで、私はそれに遭遇しました。これを繰り返し実行すると、次のコードを含むフォームにボタンを追加し、繰り返しクリックすることで、繰り返し可能なエラーを減らすことができます(注意したように、デバッガで実行中に問題は発生しません)。
form.ReportViewer.SetDisplayMode(DisplayMode.PrintLayout);
form.ReportViewer.SetDisplayMode(DisplayMode.Normal);
ReportViewerの[更新]ボタンをクリックすると、レポートの内部更新ルーチンが起動します。あなたがあれば、ReportRefreshイベントが発生していることを
private void OnRefresh(object sender, EventArgs e)
{
try
{
CancelEventArgs e1 = new CancelEventArgs();
if (this.ReportRefresh != null)
this.ReportRefresh((object) this, e1);
if (e1.Cancel)
return;
int targetPage = 1;
PostRenderArgs postRenderArgs = (PostRenderArgs) null;
if (sender == this.m_autoRefreshTimer)
{
targetPage = this.CurrentPage;
postRenderArgs = new PostRenderArgs(true, false, this.winRSviewer.ReportPanelAutoScrollPosition);
}
this.RefreshReport(targetPage, postRenderArgs);
}
catch (Exception ex)
{
this.UpdateUIState(ex);
}
}
お知らせをして:(Microsoftは今、これをオープンソース有しているが、あなたがMSコード参照サイト上で見つけることができますので、JetBrainsのdotPeekを使用して抽出)このコードは次のようになりますこのイベントをキャンセルしないと、ReportViewerは引き続きレポートを処理して再レンダリングします。イベントハンドラ内にあるコードは、ReportViewerにリフレッシュを指示します。リフレッシュは、基本的に、自分のコードと同じようにReportViewerをホイップするという同じ問題を設定します。
私はもともと、MS Connectの公式のバグレポートを提出するというアイデアでこれをさらに分離することを意図していましたが、私が気を付けるほどウサギの穴まで遠くまで行ってきました。私たちは、コールスタックから知っていることは、スレッドが実行コンテキストを切り替えていることである:火災をOnAsyncLocalContextChangedとき
Description: The application requested process termination through System.Environment.FailFast(string message).
Message: An exception was not handled in an AsyncLocal<T> notification callback.
Stack:
at System.Environment.FailFast(System.String, System.Exception)
at System.Threading.ExecutionContext.OnAsyncLocalContextChanged(System.Threading.ExecutionContext, System.Threading.ExecutionContext)
at System.Threading.ExecutionContext.SetExecutionContext(System.Threading.ExecutionContext, Boolean)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart(System.Object)
、それは変更通知のためのコールバックを処理しようとします。これらのコールバックの
[SecurityCritical]
[HandleProcessCorruptedStateExceptions]
internal static void OnAsyncLocalContextChanged(ExecutionContext previous, ExecutionContext current)
{
List<IAsyncLocal> previousLocalChangeNotifications = (previous == null) ? null : previous._localChangeNotifications;
if (previousLocalChangeNotifications != null)
{
foreach (IAsyncLocal local in previousLocalChangeNotifications)
{
object previousValue = null;
if (previous != null && previous._localValues != null)
previous._localValues.TryGetValue(local, out previousValue);
object currentValue = null;
if (current != null && current._localValues != null)
current._localValues.TryGetValue(local, out currentValue);
if (previousValue != currentValue)
local.OnValueChanged(previousValue, currentValue, true);
}
}
List<IAsyncLocal> currentLocalChangeNotifications = (current == null) ? null : current._localChangeNotifications;
if (currentLocalChangeNotifications != null && currentLocalChangeNotifications != previousLocalChangeNotifications)
{
try
{
foreach (IAsyncLocal local in currentLocalChangeNotifications)
{
// If the local has a value in the previous context, we already fired the event for that local
// in the code above.
object previousValue = null;
if (previous == null ||
previous._localValues == null ||
!previous._localValues.TryGetValue(local, out previousValue))
{
object currentValue = null;
if (current != null && current._localValues != null)
current._localValues.TryGetValue(local, out currentValue);
if (previousValue != currentValue)
local.OnValueChanged(previousValue, currentValue, true);
}
}
}
catch (Exception ex)
{
Environment.FailFast(
Environment.GetResourceString("ExecutionContext_ExceptionInAsyncLocalNotification"),
ex);
}
}
}
ひとつ投げていますOnAsyncLocalContextChangedがイベントログにエントリを書き込んですぐにアプリケーションを終了させるtry/catchでEnvironment.FailFastを呼び出す例外が発生しました。
ReportViewerが爆発する前にボタンをランダムにクリックすることができるため、この問題には競合状態のすべての特徴があります。今のところ、私たちはそれを避ける方法を知っています。私の場合は、レポートを更新する前に表示モードを設定する必要があります。あなたにとって、ReportRefreshイベントをキャンセルすると、重複した処理が回避され、その理由がわからなくても問題が解決されます。たぶんそこにいる誰かがそれをさらに気にすることがあります。
16:18:59の.NETランタイムエラーは何ですか? –
@ScottChamberlain私は16:18:59に最初のクラッシュを経験しました。その後、アプリケーションを再起動し、もう一度[更新]ボタンをクリックすると、16時19分20秒にクラッシュする可能性があります。したがって、16:18:59の.NETランタイムエラーは、16:19:20の.NETランタイムエラーとまったく同じです。 – Mark