Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 49

0
votes
answers
24 views
+10

通過PendingIntent在後臺線程中啓動服務

0

我想在Android中探索Services的世界,我剛剛寫了一個小例子,其中活動有一個觸發通知的按鈕。通過PendingIntent在後臺線程中啓動服務

的步驟我是:

  • 創建Intent intent = new Intent(context, MyService.class);
  • PendingIntent插入這一點,並把它發送到NotificationManager

然後,當我點擊該通知,服務( MyService)已啓動並啓動音樂配樂。

使用記錄我看到按鈕的點擊的MyService動作都發生在主線程,我想知道我怎樣才能使該服務運行在一個單獨的後臺線程

附:因爲這最後一個終止執行一次

沙发
0
0

onStartCommand()被稱爲主線程在ServiceMyService正在擴大Service而不是IntentService。如果您想啓動背景Thread來完成這項工作,您可以創建自己的Thread並在onStartCommand()內啓動它。事情是這樣的:

Thread t = new Thread(new Runnable() { 
    public void run() { 
     // Put whatever code you want to run in background thread here 
    } 
}).start(); 

請確保您有將關閉正在運行的後臺線程,如果必要時您Service需要停止代碼。

+0

謝謝大衛,我會嘗試:)我認爲這是整個服務是需要在單獨的線程中啓動 – kioli

板凳
0
0

你有沒有使用過RXjava?

1得到librery: 寫在的build.gradle這兩條線:

編譯 'io.reactivex.rxjava2:rxandroid:2.0.1'

編譯「io.reactivex .rxjava2:rxjava:2.1.2' 在onStartCommand

2 - 寫這些行:

io.reactivex.Observable.just(s).subscribeOn(AndroidSchedulers.mainThread()) 
                .observeOn(Schedulers.io()) 
                .subscribe(new io.reactivex.Observer<String>() { 
                 @Override 
                 public void onSubscribe(@NonNull Disposable d) { 

                 } 

                 @Override 
                 public void onNext(@NonNull String s) { 

                  //Write what you want here!! ;) 

                 } 

                 @Override 
                 public void onError(@NonNull Throwable e) { 

                 } 

                 @Override 
                 public void onComplete() { 

                 } 
                }); 

和內部onNext寫你什麼都想要,它會在執行後臺線程

我希望這將是有益的

+0

謝謝Mostafa,當時我試圖做到這一點,沒有外部庫:) – kioli

0
votes
answers
50 views
+10

C++ boost ::線程,如何啓動線程內的線程

6

如何在對象內啓動線程?例如,C++ boost ::線程,如何啓動線程內的線程

class ABC 
{ 
public: 
void Start(); 
double x; 
boost::thread m_thread; 
}; 

ABC abc; 
... do something here ... 
... how can I start the thread with Start() function?, ... 
... e.g., abc.m_thread = boost::thread(&abc.Start()); ... 

這樣,以後我可以這樣做,

abc.thread.interrupt(); 
abc.thread.join(); 

感謝。

沙发
0
6

使用boost.bind:

boost::thread(boost::bind(&ABC::Start, abc)); 

你可能需要一個指針(或一個shared_ptr):

boost::thread* m_thread; 
m_thread = new boost::thread(boost::bind(&ABC::Start, abc)); 
+0

謝謝蓋伊,它工作得很好。 – 2607 2012-02-26 23:50:26

板凳
0
15

你既不需要綁定,也不指針。

boost::thread m_thread; 
//... 
m_thread = boost::thread(&ABC::Start, abc); 
+0

+1:你說得對。有一個參數相當於使用綁定的構造函數。我更喜歡綁定,因爲我發現它更具可讀性。還有支持移動線程,我想我喜歡指針,因爲我知道發生了什麼(複製與移動),但希望一切都朝着移動... – 2012-02-27 21:26:59

+0

這應該是接受的答案 – user463035818 2017-06-01 14:08:43

0
votes
answers
35 views
+10

如何從其他線程訪問主UI線程中的System.Windows.Threading.Dispatcher?

1

我讀過,我們無法從其他工作線程訪問Silverlight應用程序的主UI線程中的任何內容。如何從其他線程訪問主UI線程中的System.Windows.Threading.Dispatcher?

那麼,爲什麼有可能訪問一個類System.Windows.Threading.Dispatcher的對象,該對象與其他工作線程中的主UI線程關聯時,我們想要委派一些工作在用戶界面上完成?

public partial class DispatcherExample : UserControl 
{ 
    public void AnyFunctionExecutingInSomeOtherThread() 
    { 
    this.Dispatcher.BeginInvoke(SomeDelegate); 
    } 
} 
沙发
0
4

A Dispatcher實例可以從任何線程訪問,因爲它沒有線程關聯。如果它確實具有線程相關性,那麼它本質上是無用的,因爲它的主要目的是將消息從任何線程分發到正確的線程。

0
votes
answers
27 views
+10

分配對象到另一個線程

-3

我有多線程的應用程序,我有一個關於在線程之間分配對象以及如何正確鎖定它們的問題。分配對象到另一個線程

我定義了自定義類型類,並在主線程中創建了該類型的實例。我想爲線程分配不同的對象,這些對象將用在線程的Execute方法中。

type TMyClass = class 
private 
    FData: Integer; 
public 
    property Data: Integer read FData write FData; 
end; 

TMyThread = class(TThread) 
private 
    FMyObject: TMyObject; 
    FLock: TCriticalSection; 

protected 
    procedure Execute; override; 
public 
    procedure Lock; 
    procedure Unlock; 
    property MyObject: TMyObject read FMyObject write FMyObject; 
end; 

procedure TMyThread.Lock; 
begin 
    FLock.Acquire; 
end; 

procedure TMyThread.Unlock; 
begin 
    FLock.Release; 
end; 

procedure TMyThread.Execute; 
begin 

    while not Terminated do 
    begin 
    Lock; 
    try 
     if Assigned(FMyObject) then 
     FMyObject.Data := FMyObject.Data + 1; 
    finally 
     Unlock; 
    end; 
    end; 
end; 


from main thread: 

var MyObject1, MyObject2: TMyObject; 
    thOperation: TMyThread; 
    CurrData1, CurrData2: Integer; 

begin 
    // create two objects 
    MyObject1 := TMyObject.Create; 
    MyObject2 := TMyObject.Create; 

    // create thread(started) 
    thOperation := TMyThread.Create(false); 

    thOperation.Lock; 
    try 
    thOperation.MyObject := MyObject1; 
    finally 
    thOperation.Unlock; 
    end; 

    /// .... do some stuff in main thread 
    thOperation.Lock; 
    try 
    CurrData1 := thOperation.MyObject.Data; 
    finally 
    Unlock; 
    end; 

    // let's assign new object on a running thread 
    thOperation.Lock; 
    try 
    thOperation.MyObject := MyObject2; 
    finally 
    thOperation.Unlock; 
    end; 

    /// .... do some stuff in main thread again 
    thOperation.Lock; 
    try 
    CurrData2 := thOperation.MyObject.Data; 
    finally 
    Unlock; 
    end; 


    if CurrData1 <> CurrData2 then ShowMessage('Different result!'); 


    // do cleanup 
    thOperation.Terminate; 
    thOperation.WaitFor; 
    thOperation.Free; 

    MyObject1.Free; 
    MyObject2.Free; 


end; 

當將不同的對象分配給線程時,這種鎖定方法是否正常?

+2

你預見了什麼問題? –

+0

我想知道這是好的解決方案還是有沒有更好的方法來做到這一點? – Nix

+0

沒有更多的背景知識,很難說你在做什麼。不知道這一點,很難提出任何更好的方法。這似乎更適合[CodeReview](http://codereview.stackexchange.com/)... –

沙发
0
1

要回答你的問題,是的,你使用TCriticalSection的方法是可以的。

有關多線程的更多信息,如果您還沒有它,Google會爲Martin Harvey提供的'Multithreading - The Delphi way'。一篇優秀的文章(或者我應該說的是書)。

0
votes
answers
9 views
+10

老問題:如何立即殺死一個線程在c#

1

我正在寫一個國際象棋遊戲,它允許兩個程序競爭,玩家需要寫一個DLL並公開一個函數來告訴主應用程序這個玩家將在下一步移動,假設函數看起來像老問題:如何立即殺死一個線程在c#

public static void MoveNext(out int x, out int y, out int discKind); 

在象棋遊戲應用時,我開始一個新的線程來調用播放器的DLL暴露得在那裏他將在轉彎移動的功能,我開始一個計時器,以防止玩家超時

private Thread mPlayerMoveThread; 

private void SetPlayerToMove(IPlayer player) 
     { 
      this.CurrentPlayer = player; 

      try 
      { 

        System.Threading.Timer mTimeoutTimer = 
            new Timer(new TimerCallback(TimeIsUp), 
            null, 
            this.mMaxTimeOfOnePlayer, 
            Timeout.Infinite); 

        mPlayerMoveThread = new Thread(this.ThreadMethodPlayerAction); 
        mPlayerMoveThread.IsBackground = true; 
        mPlayerMoveThread.Start(); 
      } 
      catch(Exception ex) 
      { 
       //// invalid move, so finish the game 
       HandleInvalidMove(player.Color, ex); 
      } 
     } 

private void ThreadMethodPlayerAction() 
     { 
      this.CurrentPlayer.MoveNext(); 
     } 

     private void KillThread(Thread thread) 
     { 
      if (thread == null || thread.ThreadState == ThreadState.Stopped) 
       return; 

      try 
      { 
       thread.Abort(); 
       thread.Join(); 
      } 
      catch 
      { 
      } 
      finally 
      { 
       thread = null; 
      } 

     } 

     private void TimeIsUp(object state) 
     { 
      // kill the threads 
      KillThread(mPlayerMoveThread); 

      HandleInvalidMove(this.CurrentPlayer.Color, new Exception("timeout")); 
     } 

我的問題是: 我的功能KillThread正確地殺死一個線程?如果不是的話,我應該怎麼做才能阻止他們?

沙发
0
2

使用Thread.Abort已經是不好的做法,因爲它會在任意點處拋出ThreadAbortedException。它允許finally子句執行。因此,如果終端內有無限循環,它不會終止該線程。

正確的方法是卸載包含該線程的整個AppDomain。將每個玩家的dll加入自己的AppDomain。這樣,您可以在不破壞主應用程序狀態的情況下強制卸載它。

+0

我喜歡'AppDomain'的想法,你會給我一些簡單的代碼來說明如何做到這一點? – 2011-03-10 05:31:09

+0

我還沒有和他們合作過。但是'Hosting'和'AppDomain'應該給出一些搜索結果。如果您需要沙盒,我建議您查看.net 4模型,它比舊模型更容易。 – CodesInChaos 2011-03-10 08:37:53

板凳
0
0

殺死一個線程是可能的,但是一個非常糟糕的方法。爲什麼不要讓你的玩家向DLL提供一個「中止」函數?你可以做,但將其添加到你的界面。如果播放器捕獲到ThreadAbortException並且不執行任何操作,Abort可能不會停止一個線程。

+0

'catch'塊退出後重新拋出異常。所以他不能像其他例外那樣捕捉它。但是,當然如果'catch' /'finally'塊沒有退出線程將不會終止。 – CodesInChaos 2011-03-09 09:19:54

+0

爲什麼不只是要求你的玩家向DLL提供一個「中止」函數呢? ----假設玩家的函數'MoveNext'中有一個無限循環,那麼玩家提供的'Abort'函數如何退出? – 2011-03-10 05:32:44

地板
0
0

你的代碼可能會殺死線程,但並不是絕對的保證。例如,當你試圖殺死的線程回滾它的調用堆棧時,它會執行任何最後的塊 - 所以你依賴那些不掛起的代碼。因爲你的問題似乎意味着線程正在運行的代碼將由其他人編寫,編寫它的人可能沒有預料到會中止線程的嘗試,所以依靠線程的行爲是不明智的。 (你也不明智的依靠編寫的代碼來清理它在線程終止前可能擁有的所有資源)

如果你想絕對100%保證能夠殺死正在計算的線程此舉,我相信通常的方法是讓一個單獨的進程託管該線程 - 然後您可以終止進程。但是,這假定您不介意每次需要計算移動時開始新進程時的性能影響。

0
votes
answers
21 views
+10

C#線程問題

0

我想做一件簡單的事情。C#線程問題

我有一個輔助線程正在聽USB讀卡器,當讀卡器「讀取」某些內容時,線程會觸發一個事件。那個事件啓動一個計時器,但計時器不起作用,我相信這是因爲關於線程。

此外,計時器必須更改窗體中的一些圖像,所以這必須在主線程中完成。

我希望我很清楚。

private void listenReader() 
    { 
     while (whileState) 
     { 

       if (readsSomething) 
       { 
        evt.OnSomeEvent(); 
        break; 
       } 

     } 
    } 

    private void eventStartsThisMethot(){ 
     //do a lot of things and start the timer 
     } 

    private void counter(){ 
     pictureBox.Image = Resources._5; 
    //the timer ticks this methot 
    } 

所以,聽讀者必須對原因很明顯單獨的線程,但第二個方法必須從主線程來完成,所以我用一個事件,但如果你有另一個想法。

感謝

+1

因此,如果該線程觸發啓動計時器的事件,誰正在監聽此計時器?另外,你正在使用哪個計時器類? – leppie 2012-07-20 21:44:21

+3

澤維爾,如果沒有發佈能夠證明您的問題的代碼示例,將很難獲得任何有意義的答案。 – 2012-07-20 21:45:30

+1

'我希望我明白:S'我恐怕你不是。 – 2012-07-20 21:53:00

沙发
0
2

既然你加入[圖片框]標籤,我們可以認爲這是Windows窗體(的WinForms)。您的閱讀器線程的事件處理程序將在閱讀器線程上執行,並且需要在UI線程上執行代碼(以響應事件)。

您可以使用窗體的BeginInvoke方法在UI線程上執行任意代碼

private void ProcessMessageOnUIThread(YourMessageType msg) 
{ 
    // Process here 
} 

private void ReaderThreadEventHandler(YourMessageType msg) 
{ 
    // Invoke the UI thread to process the message 
    BeginInvoke(new Action(ProcessMessageOnUIThread), msg); 
} 
+0

這就是它:)非常感謝 – 2012-07-20 22:20:31

板凳
0
0

計數器方法可以檢查當前線程可以更新圖片框,如果沒有,就可以通過執行來可以這樣的線程:

private void Counter() 
{ 
    if (pictureBox.InvokeRequired) 
    { 
     Action action = Counter; 
     pictureBox.Invoke(action); 
     return; 
    } 

    pictureBox.Image = Resources._5; 
} 

我還建議你使用Pascal格爲你的方法名稱 - 這是非常標準的。 Capitalization Conventions

0
votes
answers
18 views
+10

在另一個線程中調用Thread.sleep()時UI線程被阻塞

0

我試圖從UI-Thread中讀取一個名爲PcmDataReaderRunnable中的SD卡中的文本文件,並相應地更新TextView statusTextView
我正在使用handler將消息從PcmDataReader傳遞給UI線程。

爲了能夠觀察statusTextView的更改,我已將Thread.sleep(5000)放入PcmDataReader

的問題是,在UI線程被阻塞,直到I/O &睡眠完成&最後的更新,即文件「文件讀取完成。。」僅在statusTextview上顯示。
我在這裏錯過了什麼?
以下是我的代碼:在另一個線程中調用Thread.sleep()時UI線程被阻塞



MainActivity.java:

package com.example.pcmreader; 

import android.Manifest; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.support.v4.app.ActivityCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.TextView; 
import android.widget.Button; 


public class MainActivity extends AppCompatActivity implements View.OnClickListener{ 
    private TextView statusTextView ; 
    priavte Button updateButton; 

    private PcmDataReader pcmData = new PcmDataReader(); 
    private static Handler handler; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     handler = new Handler() 
     { 
      @Override 
      public void handleMessage (Message message) 
      { 
       String msg = (String) message.obj; 
       if (statusTextView != null) 
        statusTextView.setText(msg); 
      } 

     }; 

     setContentView(R.layout.main); 

     statusTextView= (TextView) findViewById(R.id.statusTextView); 

     ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 100); 

    updateButton.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view) 
    { 
    statusTextView.setText("Initiating Read .. "); 
     pcmData.run(); 

    } 

    public static Handler getHandler() 
    { 
     return handler; 
    } 
} 



PcmDataReader.java:

package com.example.pcmreader; 


import android.os.Bundle; 
import android.os.Environment; 
import android.os.Handler; 
import android.os.Message; 
import android.os.SystemClock; 
import android.util.Log; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 


public class PcmDataReader implements Runnable 
{ 
    private int [] samples = new int[6000]; 
    private int i; 
    private boolean completedReading; 
    private File sdcard = Environment.getExternalStorageDirectory(); 
    private File file = new File(sdcard,"rishav_log.txt"); 

    @Override 
    public void run() 
    { 

     i=0; 
     completedReading = false; 
     try 
     { 
      BufferedReader br = new BufferedReader(new FileReader(file)); 
      String line; 
      Handler uiHandler= MainActivity.getHandler(); 
      Message msg = uiHandler.obtainMessage(); 
      msg.obj="File openned, Reading data.."; 
      uiHandler.sendMessage(msg); 

      while ((line = br.readLine()) != null) 
       samples[i++]=Integer.parseInt(line); 

      Thread.sleep(5000); //dummy sleep to observe the update of textView in UI thead 
      br.close(); 
      completedReading = true; 

      msg = uiHandler.obtainMessage(); 
      msg.obj="File Reading Complete.."; 
      uiHandler.sendMessage(msg); 
     } 
     catch (IOException e) 
     { 
      Log.i("file read",e.getMessage()); 
     } 
    catch (InterruptedException e) 
    { 
      e.printStackTrace(); 
     } 
    } 

} 
+0

代碼中根本沒有多線程...... – Selvin

0
votes
answers
44 views
+10

當焦油和分裂時使用所有核心

0

我想讓我的tar命令使用所有內核(8),當我打包到如下所示的單個包中時,我得到它的工作:tar -I pigz -cf packed.tar.gz folder/。 它正在工作,它使用所有內核。當焦油和分裂時使用所有核心

但是,當我需要打包成多個文件時,我無法使用它來使用所有內核,這是我的命令:tar cvzf - folder/ | split --bytes=4GB - packed.tar.gz。 如何讓這個命令使用所有核心而不僅僅是一個?

感謝您的所有意見。

沙发
0
2

對於多線程文件壓縮工具pigz:

tar -I pigz -cvf - folder/ | split --bytes=4GB - packed.tar.gz 
0
votes
answers
9 views
+10

從另一個線程操作線程

2

在c#中的程序中,我有2個線程與主線程分開。 當用戶關閉表單時,我想終止主線程中的一個線程。 我該如何去做呢?如果可能,請向我提供代碼。從另一個線程操作線程

0
votes
answers
25 views
+10

在新線程中啓動方法

0

我有一個向量指針的對象,我試圖在一個新線程(方法有一個參數)啓動對象的方法。在新線程中啓動方法

這是代碼,我不能編譯:

class CanaSynchDynamic { 
... 
    void start() (boost::barrier&); 
... 
}; 

,並在主:

for(int i=0;i<pw;++i) 
    vS1.push_back(new CanaSynchDynamic()); 

do { 
     boost::barrier barrier(pw); 
     boost::thread_group threads; 
     for(int i=0;i<pw;++i) 
      vS1[i]->more_steps(start,s[z]); 
     for(int i=0;i<pw;++i) 
      threads.create_thread(boost::bind(&CanaSynchDynamic::start,boost::ref(*(vS1[i])),boost::ref(barrier))); 
     threads.join_all(); 

} while(something); 

錯誤是:

/usr/include/boost/thread/detail/thread.hpp: In instantiation of 'void 
    boost::detail::thread_data<boost::reference_wrapper<T> >::run() [with F = CanaSynchDynamic]': 
    simulation_3.cpp:278:1: required from here 
    /usr/include/boost/thread/detail/thread.hpp:98:17: error: no match for call to '(CanaSynchDynamic)()' 

你有什麼想法?

沙发
0
2

您不能使用reference_wrapper來傳遞函數將運行的對象。相反,你可以只是一個指針傳遞給你的對象:

threads.create_thread(boost::bind(&CanaSynchDynamic::start,vS1[i],boost::ref(barrier))); 

而且,你可能只是存儲在一個向量的對象,而不是指向他們。如果您需要指針,請使用C++ 11中的std::unique_ptr,或者如果該指針不可用,則可能使用boost::ptr_vector