标签: sta

防止事件产生另一个线程

我在这里读到关于代表和事件(完全不同的原因)来自这个[网站] [1]在那里我得到的印象是,如果你的事件需要足够长的时间,就会生成一个单独的线程.那让我想到了一个我似乎无法解决的错误.所以我正在为我的MSR设备制作键盘楔程序,通过RS232端口进行通信.我创建了这个类来处理输入.

    public ComPortInput(SerialPort sp, int delay)
        : this(delay)
    {
        if (sp == null)
            throw new System.ArgumentNullException("Serial port can not be null");

        serialPort = sp;
    }
Run Code Online (Sandbox Code Playgroud)

当我打开这个ComPortInput类时,我订阅了DataReceived事件.如果我正确猜测,那么如果我将延迟设置得足够高,那么我的dataevent将创建一个新线程.我认为通过查看我的代码可以最好地描述问题.

Program.cs中

    [STAThread]
    static void Main()
    {
        singleton = new System.Threading.Mutex(true, "Keymon");
        if (!singleton.WaitOne(System.TimeSpan.Zero, true))
        { return; }

        InstantiateProgram();
        System.Windows.Forms.Application.Run(main);
    }
    private static void InstantiateProgram()
    {
        System.Windows.Forms.Application.EnableVisualStyles();
        System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
        main = new frmMain();
    }
Run Code Online (Sandbox Code Playgroud)

ComPortInput.cs.只是datareceived事件

    void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (Delay > 0)
            System.Threading.Thread.Sleep(Delay); //waits for all the data to be sent to …
Run Code Online (Sandbox Code Playgroud)

c# polymorphism events mta sta

2
推荐指数
1
解决办法
334
查看次数

在STAThread和MTAThread之间切换以及内存泄漏

在vb.net WebService中查找内存泄漏时,我检测到阻塞的终结器,以及从未发布的几个对象(例如System.Threading.ReaderWriterLock)

Google告诉我这可能是因为STAThread属性是在我的main方法上设置的.我花了很长时间才发现VB.net使用STA作为默认值,而c#使用MTA.

当我将MTAThread-Attribute添加到我的Main方法时,一切正常,对象被释放.因此,如果我理解正确,则在STA模式中阻止Finalizer-Thread.

到目前为止一切顺利,但说实话,我今天第一次听说STA和MTA.可以在没有任何想法的情况下在STA和MTA之间切换吗?

更新 我仍然不确定我是否可以在不破坏我的代码的情况下在MTA和STA之间切换.这是一些更多的想法

  • 我不在我的代码中使用COM对象.
  • 但我正在使用的其他一些库似乎在引擎盖下使用它们,例如OracleCommand
  • 我的应用程序是用vb.net编写的,所以很有可能它被设置为STA-Appartment,因为这是vb.net的默认值,我在开发时不知道
  • 如果我在c#中编写了我的应用程序,默认情况下会将其设置为MTA
  • 那么我需要关心引擎盖下使用的COM对象吗?

c# vb.net mta sta

2
推荐指数
1
解决办法
1727
查看次数

具有多个STA线程的Wpf应用程序仍会阻止用户界面

不久前,我们使用IronPython将Python脚本添加到Wpf应用程序中.起初,它只是"奴隶",因为例如按钮点击调用脚本然后只是运行完成将控制权返回给Wpf.后来我们添加了'master'脚本:脚本在它自己的线程中运行,并控制应用程序的其余部分.这是相当具有挑战性的,但过了一段时间,在现有的SO内容的帮助下,我们看起来很有效.从来没有真正使用它,直到现在,不幸的是事实证明它不能正常工作.核心原因是虽然有两个单独的STA线程(主要的Wpf一个和一个脚本),因此两个不同的Dispatcher实例,主线程似乎被阻止,因为脚本线程在循环中等待主线程完成(响应在脚本线程上处理的按钮单击并在主线程上启动事件).使用具有单独ui窗口的两个线程的全部意义当然不会发生.到底是怎么回事?

更新它是可重复使用最少的代码,所以我链接到它而不是在这里发布伪代码.在创建代码时,我发现当脚本线程创建的窗口未嵌入(设置MainWindow.hostedWin = false)时,不会发生死锁,并且一切都按预期运行.

回应评论所以有3个关注的线程发挥作用.我们称它们为Python,Ui和Process.Python启动Process并等待它完成.进程调用在Ui上调用.在那一点上不应该做任何事情:毕竟,它是阻塞的Python,而不是Ui,而这个结构的重点是Ui不应该与Python交互.好吧,除了它确实以某种方式.哪个是罪魁祸首.在僵局中,Ui坐在那里,PresentationFramework.dll!System.Windows.Interop.HwndHost.OnWindowPositionChanged(System.Windows.Rect rcBoundingBox) + 0x82 bytes而Process坐在WindowsBase.dll!System.Windows.Threading.DispatcherOperation.DispatcherOperationEvent.WaitOne() + 0x2f bytes那里,而Python就在Thread.Sleep.

这里发生了什么,以及如何解决它?

c# wpf ironpython dispatcher sta

2
推荐指数
1
解决办法
1338
查看次数

BackGroundWorker 线程中的 ShowDialog 和 UI 交互

经过2个小时的研究,我仍然找不到解决我的问题的方法。

我所做的任务是在 BackGroundWorker 线程中处理一些文件。但是,有时我需要使用 ShowDialog 让用户选择 SaveFile 位置,但我收到 STA/MTA 错误。

主窗体代码:

private void button2_Click(object sender, EventArgs e)
{
            button1.Enabled = false;
            ProcessReportWorker.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)

工作代码:

void ProcessReportWorker_DoWork(object sender, DoWorkEventArgs e)
{
    int ReportCount = Reports.Count();
    foreach (string Report in Reports)
    {
            ProcessReport NewReport = new ProcessReport(Report);
        string result = NewReport.Start();
    }
} 
Run Code Online (Sandbox Code Playgroud)

ProcessReport.Start() 代码:

class ProcessReport
{
    public string Start() 
    {
        if(File.Exists(ResultPath))
        {
            SaveFileDialog SaveReport = new SaveFileDialog();
                    SaveReport.InitialDirectory = "c:\somepath";
                    SaveReport.CheckPathExists = true;
                    SaveReport.DefaultExt = ".xls";
                    SaveReport.OverwritePrompt = true;
                    SaveReport.ValidateNames …
Run Code Online (Sandbox Code Playgroud)

c# multithreading backgroundworker sta showdialog

1
推荐指数
1
解决办法
5977
查看次数

“调用线程必须是 STA,因为许多 UI 组件都需要这个。”

我正在尝试用纯 C# 打开一个窗口。为此,我创建了一个窗口构造函数 ( SGFWindow) ,该窗口构造Window函数从以下位置扩展了该类System.Windows

namespace SGF
{
    public partial class SGFWindow : Window
    {
        public SGFWindow() 
        {
            this.Title = "SGF Window";
            this.Width = 200;
            this.Height = 200;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个WindowTest类来测试它:

namespace SGF
{
    public class WindowTest
    {
        public static void Main(string[] args)
        {
            SGFWindow window = new SGFWindow();
            window.Show();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,我收到“调用线程必须是 STA,因为许多 UI 组件都需要这个”。错误 ; 只不过这不是一个线程(或者不是我创建的线程?)。

我搜索了它,但它总是关于一个线程,我找不到如何修复这个错误。我也看到过一些东西[STAThread],但显然不适合它。

预先感谢,马索。

c# wpf multithreading sta

-2
推荐指数
1
解决办法
1732
查看次数