からインスタンスを注入された:私は持って行動がFoo.DoSomething
が呼び出されるということですシンプルインジェクタ - アクセスは、私は次のような何かを持っている私が働いているアプリ内SimpleInjectorを使用していますバックグラウンドスレッド
public class Foo : IFoo
{
private readonly Bar _bar;
public Foo(Bar bar)
{
_bar = bar;
}
public void DoSomething()
{
IEnumberable<Order> orders = _bar.Orders;
}
}
バックグラウンドスレッド(Task.Run)とBar
は、シングルトンのライフスタイルを持つアプリ(Windowsフォームアプリ)のMainメソッドに登録されています。私が気になるのは、Foo
に提供されたBar
の実装がスレッドセーフではない場合です。
私の主な問題は、Foo
によって必要とされる状態がBar
であり、この状態がメインスレッドによって先に設定されてからFoo.DoSomething
が呼び出される前です。私は直面しているこのような状況に対する解決策を見回しましたが、私が助けてくれたものは見つけられませんでした。
私はthisページの提案を見てきました。このページは、インスタンスがバックグラウンドスレッドで実行されたときにデコレータを使用しています。しかし、Bar
の状態が別のスレッド(メインスレッド)に設定されているため、デコレータを使用すると、状態のないBar
という新しいインスタンスが作成されるだけです。
私はバグをシングルトンとして登録し、登録された実装がスレッドセーフであることを確認しなければならないと思っていますか、またはこの問題の明らかな解決策があります。私は見ることができない?
私が提供した情報は十分です。あなたが何か詳しい情報が必要なら私に教えてください。
おかげ
更新 Bar
単にアプリは全体で必要情報のリストを保持するクラスです。たとえば:
public class Bar: IBar
{
// Not using orders or products, but just for purpose of the example
// These are initialized early on in the App process because early
// steps of the app (which are on the main thread) need them.
public IEnumerable<Order> Orders { get; private set; }
public IEnumerable<Product> Products { get; private set; }
}
次は私がfooを使用して、フォームのアプリです:
public partial class App: Form
{
private readonly IFoo _foo;
public App(IFoo foo)
{
InitializeComponent();
_foo = foo;
}
public btn1_Click()
{
// This is just for the purpose of showing that the data inside Bar
// is loaded on the main thread before Foo.DoSomething is run. In
// the real app the Bar data is loaded at previous steps of the app
// (the app is a wizard like app).
LoadBarData();
Task.Run(() =>
{
_foo.DoSomething();
});
// The issue would be if for example Bar is changed here while the
// background thread is running. In my app it doesn't really change
// here, but I want to make sure no issues arise in all scenarios,
// whether it changes or not.
}
}
そして最後にここで私の主な方法です。バーが登録されている
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (Container container = new Container())
{
container.Register<IBar, Bar>(Lifestyle.Singleton);
container.Register<IFoo, Foo>(Lifestyle.Singleton);
container.Register<App>();
}
Application.Run(container.GetInstance<App>());
}
バーとメインに関連するコードを表示してください。 – Steven
@Steven私は質問を編集してより多くの情報を追加しました。それが役に立てば幸い。ありがとうございました –